概述
autowireByName
@Configuration
@ComponentScan("com.su.spring.common")
public class CommonConfig {
}
@Service
public class UserService {
UserDao userDao;
public void query(){
System.out.println("UserService query() -----------");
userDao.query();
}
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
}
@Repository()
public class UserDao {
public void query(){
System.out.println("UserDao query() -----------");
}
}
通过自定义BeanDefinitionRegistryPostProcessor设置UserService的属性自动装配模式为byName
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
GenericBeanDefinition beanDefinition = (GenericBeanDefinition) registry.getBeanDefinition("userService");
beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);
registry.registerBeanDefinition("userService",beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
接下来,我们直接从populateBean方法进行分析吧
接下来我们进入applyPropertyValues看看,spring是怎么通过setUserDao(UserDao userDao)这个writeMethod来完成属性注入的
经过了一些调用后,最终调用下面这个方法完成属性的注入
值的注意的是,autowwiredByName需要和set方法一起使用,才能够完成属性的注入。
autowireByType
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
GenericBeanDefinition beanDefinition = (GenericBeanDefinition) registry.getBeanDefinition("userService");
beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
registry.registerBeanDefinition("userService",beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
}
}
这时候进入的是populateBean的autowiredByType了
之后的流程和autowiredByName一样。
AUTOWIRE_NO
如果没有通过自定义BeanDefinitionRegistryPostProcessor设置UserService的属性自动装配模式,spring默认是AUTOWIRE_NO,那么UserService属性需要加@Autowired注解才能完成自注入
@Service
public class UserService {
@Autowired
UserDao userDao;
public void query(){
System.out.println("UserService query() -----------");
userDao.query();
}
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
}
那么接下来,我们进入AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法看看吧
那么,@Autowired是根据ByName还是ByType来完成属性注入的呢?
这里,我们对测试类稍微调整一下,定义一个接口Dao,有两个实现类。一个是UserDao,另一个是UserDao2。
@Service
public class UserService {
@Autowired
Dao dao;
public void query(){
System.out.println("UserService query() -----------");
dao.query();
}
}
接下来,我们就要分析一下上面的beanFactory.resolveDependency的调用了。
最终会抛出异常出来
加@Qualifier限定后就能完成正常注入了。
在调整下测试类
@Service
public class UserService {
@Autowired
Dao userDao2;
public void query(){
System.out.println("UserService query() -----------");
userDao2.query();
}
}
Dao还是有两个实现类UserDao、UserDao2,这种情况下,又是怎么完成属性注入的呢?
来看下determineAutowireCandidate方法
总结:@Autowired属性注入,其实是根据ByType获取所有符合类型的Bean,然后通过ByName进行过滤。
最后
以上就是老迟到煎饼为你收集整理的Spring自动注入源码分析的全部内容,希望文章能够帮你解决Spring自动注入源码分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复