@Autowire/@Value注解实现

        在Spring中,autowire注解的功能主要是通过AutowiredAnnotationBeanPostProcessor类来实现的,AutowiredAnnotationBeanPostProcessor类本身会通过xml标签"context:annotation-config" and "context:component-scan"进行注册,可以去掉或者管理默认的注解配置,如果你希望去声明一个个性化的AutowiredAnnotationBeanPostProcessor bean定义。注意:注解注入会在XML注入之前执行,后来的配置会覆盖前边所有途径的配置。下边是AutowiredAnnotationBeanPostProcessor的类图。 

        我们从最上边的类来分析下,首先是BeanPostProcessor类,这个类是bean工厂的hook,用于对新建的bean实例的个性化的改造,比如检查标记接口(类似Serializable)或者通过代理来包装bean。ApplicationContexts可以自动检测到自身bean定义中的BeanPostProcessor类,并应用到后续创建的bean。简单的bean工厂允许通过编程式的注册post-processor,可以对所有通过这个工厂创建的bean生效。特别的,Post-processors处理标记接口的bean通常会实现postProcessBeforeInitialization,而通过代理来包装bean的post-processors通常会实现postProcessAfterInitialization。

     InstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口,在BeanPostProcessor的基础之上添加了两个回调,一个是before-instantiation,另一个是after-instantiation,但在属性被赋值或者注入之前。通常被用于控制特定bean的默认实例化过程,比如用特殊的TargetSource创建(池化目标,懒初始化目标)代理,或者实现额外的诸如策略,如属性注入。

        SmartInstantiationAwareBeanPostProcessor扩展了InstantiationAwareBeanPostProcessor接口,加了一个回调,用来推断被处理bean的实际类型。

        InstantiationAwareBeanPostProcessorAdapter类实现了InstantiationAwareBeanPostProcessor接口,所有的方法都是一个空实现,不会改变容器实例化的bean的正常的处理。子类可以根据需要实现该类的某几个方法。

        除了上边的这几个接口(类),上图中还有一个接口MergedBeanDefinitionPostProcessor,这个是运行时复合bean定义的回调接口。BeanPostProcessor的实现可以实现这个子接口来后处理 符合bean的定义(原始bean定义的处理过的副本),Spring用来创建一个新的bean实例。

        接下来就是我们最主要的实现类AutowiredAnnotationBeanPostProcessor,它被用来注入带注解的属性,setter方法和任意的config方法。主要检测通过Java5中的注解来注入的类:@Autowired和@Value。注入的逻辑主要通过postProcessPropertyValues方法来实现,对于每一个新建的bean,都会调用该方法来进行注入。有两种注入方式:AutowiredMethodElement和AutowiredFieldElement,分别是方法注入和属性注入。

@Override
	public PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
        //查找需要进行注入的属性
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
            //从Spring容器中获取对应的bean或者value进行注入
			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;
	}

        上边的方法逻辑很简单, 就是先查找需要注入的数据,然后调用

inject进行注入。

 注解的原理最后竟然真的是反射,这句话听说了无数遍,直到今天见到了真容,哭。 

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值