学习笔记:BeanPostProcessor的功能原理分析,@Autowired、ApplicationContextAware的原理分析

BeanPostProcessor是一个接口,定义了两个方法,postProcessorBeforeInitialization()、postProcessorAfterInitialization()。

其中,postProcessorBeforeInitialization()方法在初始化方法执行之前,在构造方法之后执行;

postProcessorAfterInitialization()方法在初始化方法执行之后执行。

这个接口的作用主要就是在bean实例化之后,初始化前后对实例化生成的bean进行预置处理。它有很多的实现类,这里举出几个例子来分析这个接口的作用。

  • AutowiredAnnotationBeanPostProcessor,这个PostProcessor功能就是完成@Autowired注解的功能实现
  1. 测试代码
@Component
public class Dog  {
    @Autowired
    private Cat cat;
}

@Component
public class Cat {

}

      2.标注断点:进入AutowiredAnnotationBeanPostProcessor类,在它的内部类AutowiredFieldElement的inject()方法上标注断点,这个内部类使用来处理属性赋值的

      3. debug启动,发现进入到这个方法之中

protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
            //要赋值的属性,本例中为cat
			Field field = (Field) this.member;
			Object value;
			if (this.cached) {
				value = resolvedCachedArgument(beanName, this.cachedFieldValue);
			}
			else {
				DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
				desc.setContainingClass(bean.getClass());
				Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
				TypeConverter typeConverter = beanFactory.getTypeConverter();
				try {
                    //这个方法就是从容器中提取出符合名字的bean,也就是Cat的bean实例
                    //如果没有这样的bean,或者有多个这样的bean,都是会报错的
                    //要注入的bean的名字和类型都存在desc属性中
					value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
				}
				catch (BeansException ex) {
					throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
				}
				synchronized (this) {
					if (!this.cached) {
						if (value != null || this.required) {
							this.cachedFieldValue = desc;
							registerDependentBeans(beanName, autowiredBeanNames);
							if (autowiredBeanNames.size() == 1) {
								String autowiredBeanName = autowiredBeanNames.iterator().next();
								if (beanFactory.containsBean(autowiredBeanName)) {
									if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
										this.cachedFieldValue = new ShortcutDependencyDescriptor(
												desc, autowiredBeanName, field.getType());
									}
								}
							}
						}
						else {
							this.cachedFieldValue = null;
						}
						this.cached = true;
					}
				}
			}
			if (value != null) {
				ReflectionUtils.makeAccessible(field);
                //将从容器中获取的bean注入到对应的属性中
				field.set(bean, value);
			}
		}
	}

总的来说,在容器启动的时候,单实例bean被实例化,此后要对bean属性赋值,此时会查看有没有对属性赋值的PostProcessor(InstantiationAwareBeanPostProcessor)存在,如果有就调用它,@Autowired注解就作用在这个时候,AutowiredAnnotationBeanPostProcessor就是InstantiationAwareBeanPostProcessor的子类,因此会调用它的postProcessPropertyValues()方法,最终会调用到AutowiredFieldElement的inject()方法来完成属性注入。

以上过程分析请自行查看方法调用栈。

  • ApplicationContextAwareProcessor,这个postProcessor的主要功能就是完成ApplicationContextAware接口向bean中注入ApplicationContext对象(也就是容器)的功能实现

1. 测试代码

@Component
public class Dog implements ApplicationContextAware,  {
   
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("setApplicationContext。。。。");
    }
}

2. 原理分析:

       此时dog Bean中就被注入了IOC容器,这是如何做到的?在方法上打个断点,debug,查看方法栈,发现这个方法执行之前执行了ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法,这个方法里又调用了这个类中的invokeAwareInterfaces()方法。在这个方法里调用了ApplicationAware接口的setApplicationContext()方法。

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;
        if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
                    return null;
                }
            }, acc);
        } else {
            //方法调用
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }

    //此方法被调用
    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
            }

            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }

            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
            }

            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
            }
            
            //判断bean是不是ApplicationContextAware的实例,我们的例子中Dog类实现了                    
            //ApplicationContextAware接口,自然就是它的实例,因而Dog类中实现的方法
            //setApplicationContext()就被调用,容器对象就被注入到Dog的bean中
            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值