上篇文章Spring中Xml配置Bean的依赖注入源码分析,讲的是通过XML方式配置Bean来实现依赖注入的,主要是通过BeanWrapperImpl.setPropertyValue方法,调用java类提供的Setter方法,利用反射机制注入属性值,完成依赖注入。
这次讲讲注解@Autowired与@Resource,是如何实现依赖注入的。
1.@Autowired实现依赖注入
测试Main代码:
public class BeanExample {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
studentService.hello();
}
}
开启注解:
java类:
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
private UserService userService;
@Override
public void hello() {
userService.hello("haha");
}
}
因为开启了注解注入,在Spring容器启动时,默认会向BeanFactory注册AutowiredAnnotationBeanPostProcessor后置处理器,也就是在Bean实例化完后,用来做依赖注入工作的。
AutowiredAnnotationBeanPostProcessor处理器就是用来实现@Autowired的依赖注入的。
到这里,就完成了@AutoWired方式的属性注入了。
PS:常见注入异常报错代码位置。
2.@Resource实现依赖注入
测试代码同上,就是注入类型@AutoWired改为@Resource。
@Resource类型注解,依赖注入的处理类是CommonAnnotationBeanPostProcessor
到这里,就完成了@Resource方式的属性的依赖注入。
这里不够准确,上面是先按名称找。autowireResouce可能按类型也可能按名称,就看你有么有给@Resource加name属性了。
下面我会上个案例。
给@Resource指定name值。
3.注解+Setter混合注入(当然正常情况,不会这么用 )
public class BeanExample {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
StudentService studentService = (StudentService) applicationContext.getBean("studentServiceImpl");
studentService.hello();
}
}
/**
* Function Desc: 注解+Setter混合注入。
* Date:2018/3/31 16:15
* author:[email protected]
*/
public class StudentServiceImpl implements StudentService {
@Resource
private UserService userService;//通过注解注入
private TeacherService teacherService;//通过Setter注入
public void setTeacherService(TeacherService teacherService) {
this.teacherService = teacherService;
}
@Override
public void hello() {
userService.hello("haha");
}
}
可以看出,Spring底层代码每个方法职责单一,结构合理。
主要流程:解析bean-》保存beanDefition到IOC容器-》根据beanDefition实例化-》根据BeanpostProcessor依赖注入
总结:
1.Autowired是Spring提供的,Resouce是JDK提供的。
2.Autowired通过AutowiredAnnotationBeanPostProcessor实现属性的依赖注入,Resouce通过CommonAnnotationBeanPostProcessor。实现属性的依赖注入。
3.注解方式实例化的bean,默认都是单例,没找到定义bean Scope的入口。
4.Autowired注解严格来说,只是按类型来注入的。因为如果按类型找不到依赖的bean,直接抛异常了。配置了多个类型的bean时,会返回指定@Primary注解的bean。
5.Resouce注解,当么有指定name时,是按类型注入的;指定了name,才按name。当然前提时,我还没弄明白jndiFactory是怎么样用的。