Spring框架中@Autowired实现自动装配的过程

一、@Autowired用法

    替换:autowire属性,自动装配(按照类型装配,通过set方法,且方法可以省略)
    位置:修饰属性,set方法
    语法:@Autowired(required="true")
    注意:1.如果容器中没有一个可以与之匹配且required属性为true则会报异常
            NoSuchBeanDefinitionException;
         2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配;
         3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常NoUniqueBeanDefinitionException;

在controller层使用@Autowired注入一个service层对象:

@Controller
public class AccountControllerImp implements IAccountController{
    @Autowired
    public IAccountService service;

    public void save(Account account) {
         service.save(account);
    }

    public void deleteById(int id) {
        service.deleteById(id);
    }

    public Account findByName(String name) {
        return service.findByName(name);
    }

    public List<Account> findAll() {
        return service.findAll();
    }
}

二、@Autowired实现自动装配的过程

        首先先了解Spring框架创建Bean对象的生命周期:实例化=>属性赋值=>初始化=>销毁。而在Spring框架对属性赋值的populateBean()方法上,有这样一段代码:


for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
}

        这段代码的意思就是首先获取到spring中所有实现了 BeanPostProcessor接口的类,并循环逐个处理,如果某个BeanPostProcessor实现类又实现了InstantiationAwareBeanPostProcessor,则调用其postProcessProperties方法,

        而@Autowired就是使用AutowiredAnnotationBeanPostProcessor注解解析器实现的,AutowiredAnnotationBeanPostProcessor类间接实现了InstantiationAwareBeanPostProcessor,而InstantiationAwareBeanPostProcessor又实现了BeanPostProcessor。

        这里就是调用@Autowired的注解解析器AutowiredAnnotationBeanPostProcessor中的postProcessProperties方法,这个方法的主要目的就是对属性进行注入。

代码如下:

@Override
	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

        这个方法中使用了两个方法,一个是findAutowiringMetadata,另一个是metadata.inject(bean, beanName, pvs)。其中,前者就是通过反射机制找到该对象所有标注了@Autowired注解的属性或方法等,并以InjectionMetadata对象返回,后者就是通过metadata对象对相关属性进行属性注入,从而实现自动装配。

三、总结

        Spring框架在很大程度上为程序业务开发降低了耦合关系,@Autowired自动装配就是Spring IOC和DI核心思想的体现,通过将对象的控制权转交给Spring框架,由IOC容器在运行时向每个bean对象注入所依赖的另一个bean对象,从而实现自动装配。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙草不加料

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值