[TOC]
一 @Autowired
通过 @Autowired 的使用来消除 set ,get方法
注:区别于Lombok,lombok是生成set和get方法,你能直接使用 ;
@Autowired 是用来注值的,spring注值本质上是用了set方法来找到对象并初始化的,在这个注解没出来前,需要写get,set方法
- 通过(1),可以看到,@Autowired 本质上是用来初始化对象的,(源城时好像是用来初始化实体类,捷顺用来初始化Dao层对象)
@Autowired默认按类型装配
注:捷顺用来初始化Dao层对象,关键是怎么和Mapper连接呢,有两种方案:
- 在Dao层接口类上 写 @Mapper 注解,表示这个接口要对接mapper文件
- 在application.xml中 添加配置:
<!-- 自动扫描了所有的XxxxMapper.java,这样就不用一个一个手动配置Mpper的映射了,只要Mapper接口类和Mapper映射文件对应起来就可以了 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.jieshun.jht.integral.dao" />
</bean>
来自 http://www.cnblogs.com/zghull/archive/2012/06/27/2565480.html
二 @Resource
这个是用来初始化对象的,这和@Autowired注解不一样,
- @Autowired默认按类型装配 ,
- @Resource按名称装配,
这是使用注解是要自己写名称的,捷顺在Controller里用初始化对象,使用这个注解,在接口实现类(impl)上使用注解 @Service(“mebershipService”)来表示这个类要放入IOC中,并指定名字,然后使用这个指定的名字就能获得对象,
如果没有指定名字就会按类型装配
来自 http://www.cnblogs.com/zghull/archive/2012/06/27/2565480.html
三 @Service
当你需要定义某个类为一个bean,则在这个类的类名前一行使用@Service(“XXX”),就相当于讲这个类定义为一个bean,bean名称为XXX;
会配合@Resource来使用
四 @Async
用法: 在方法上或者类上标注, 这样调用方法时就会异步执行, 它需要搭配 @EnableAsync
注解使用
它还有一个value值,表示指定使用哪个线程池,不指定就用叫’taskExecutor’的线程池, 连默认线程池都没有就注解自己的线程池(有内存泄露风险,而且不重用线程)
原理: Spring容器启动初始化bean时,判断类中是否使用了@Async注解,创建切入点和切入点处理器,根据切入点创建代理,在调用@Async注解标注的方法时,会调用代理,执行切入点处理器invoke方法,将方法的执行提交给线程池,实现异步执行。
需要注意的一个错误用法是,如果A类的a方法(没有标注@Async)调用它自己的b方法(标注@Async)是不会异步执行的,因为从a方法进入调用的都是它本身,不会进入代理。(称为本地调用)
mode=AdviceMode.ASPECTJ
指定切面模式就可以生效
Spring @Async之四:Aysnc的异步执行的线程池实现原理 - duanxz - 博客园 (cnblogs.com)
Spring @Async 注解的使用以及原理(一)灵颖桥人的博客-CSDN博客@async注解
@Import
@Import注解可以用于导入第三方包 ,当然@Bean注解也可以,但是@Import注解快速导入的方式更加便捷.Import注解本身在springboot中用的很多,特别是ImportSelector方式在springboot中使用的特别多
@Import的三种用法
@Import的三种用法主要包括:
- 直接填class数组方式
- ImportSelector方式【重点】
- ImportBeanDefinitionRegistrar方式
第一种用法:直接填class数组
直接填对应的class数组,class数组可以有0到多个。
语法如下:
@Import({ 类名.class , 类名.class... })
public class TestDemo {
}
对应的import的bean都将加入到spring容器中,这些在容器中bean名称是该类的全类名 ,比如com.yc.类名
第二种用法:ImportSelector方式【重点】
这种方式的前提就是一个类要实现ImportSelector接口,假如我要用这种方法,目标对象是Myclass这个类,分析具体如下:
创建Myclass类并实现ImportSelector接口
public class Myclass implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 特意换个bean名字
return new String[]{"com.yc.Test.TestDemo3"};
}
}
分析实现接口的selectImports方法中的:
- 1、返回值: 就是我们实际上要导入到容器中的组件全类名【重点 】
- 2、参数: AnnotationMetadata表示当前被@Import注解给标注的所有注解信息【不是重点】
需要注意的是selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!
案例:
@Import({TestDemo2.class,Myclass.class})
public class TestDemo {
@Bean
public AccountDao2 accountDao2(){
return new AccountDao2();
}
}
/**
* 打印容器中的组件测试
*/
public class AnnotationTestDemo {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class); //这里的参数代表要做操作的类
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String name : beanDefinitionNames){
System.out.println(name);
}
}
}
所以初始化TestDemo类时就会有三个对象被初始化
第三种用法:ImportBeanDefinitionRegistrar方式
同样是一个接口,类似于第二种ImportSelector用法,相似度80%,只不过这种用法比较自定义化注册,具体如下:
public class Myclass2 implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);
//注册一个bean指定bean名字(id)
beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);
}
}