欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > Spring源码-xxxAware实现类和BeanPostProcessor接口调用过程

Spring源码-xxxAware实现类和BeanPostProcessor接口调用过程

2024/10/24 12:30:50 来源:https://blog.csdn.net/qq_37200262/article/details/139811561  浏览:    关键词:Spring源码-xxxAware实现类和BeanPostProcessor接口调用过程

xxxAware实现类作用

以ApplicationContextAware接口为例
ApplicationContextAware的作用是可以方便获取Spring容器ApplicationContext,从而可以获取容器内的Bean


package org.springframework.context;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;/**
public interface ApplicationContextAware extends Aware {/**
设置该对象运行的ApplicationContext。通常,这个调用将用于初始化对象。
<p>在填充普通bean属性之后调用,但在初始回调之前调用,
例如{@link org.springframework.beans.factory.InitializingBeanafterPropertiesSet()}
或自定义初始化方法。
在{@link ResourceLoaderAwaresetResourceLoader}, 
{@link ApplicationEventPublisherAwaresetApplicationEventPublisher}
和{@link MessageSourceAware}之后调用,如果适用的话。
@param applicationContext这个对象要使用的applicationContext对象
@在context初始化错误的情况下抛出
ApplicationContextException 
@如果被应用程序context方法抛出则抛出BeansException @参见org.springframework.beans.factory.BeanInitializationException*/void setApplicationContext(ApplicationContext applicationContext) throws BeansException;}

下面这个例子就是ApplicationContextUtil 实现了ApplicationContextAware 这个接口,重写了setApplicationContext(ApplicationContext applicationContext)方法,在调用到这个方法的时候给类里的applicationContext 属性赋值,后续别的方法在拿到这个applicationContext进行操作,比如根据getBean方法获取Bean对象以及调用beanFactory.registerBeanDefinition(beanName, definition);方法进行添加BeanDefinition即bean的元数据信息。

public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext = null;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if (this.applicationContext == null) {this.applicationContext = applicationContext;}}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name) {return getApplicationContext().getBean(name);}//通过class获取Bean.public static <T> T getBean(Class<T> clazz) {return getApplicationContext().getBean(clazz);}/*** 同步方法注册bean到ApplicationContext中** @param beanName* @param clazz* @param original bean的属性值*/public static synchronized void setBean(String beanName, Class<?> clazz, Map<String,Object> original) {checkApplicationContext();DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();if(beanFactory.containsBean(beanName)){return;}//BeanDefinition beanDefinition = new RootBeanDefinition(clazz);GenericBeanDefinition definition = new GenericBeanDefinition();//类classdefinition.setBeanClass(clazz);//属性赋值definition.setPropertyValues(new MutablePropertyValues(original));//注册到spring上下文beanFactory.registerBeanDefinition(beanName, definition);}}

上述是相关使用,为什么实现这个接口就会调用这个set方法,接下来根据spring源码,讲解xxxAware接口的前世今生。
不重要的步骤给出调用链路

AnnotationConfigApplicationContext## AnnotationConfigApplicationContext(String... basePackages) 构造函数
AbstractApplicationContext##refresh()容器刷新
AbstractApplicationContext##prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)beanFactory的准备工作,对各种属性进行填充

prepareBeanFactory准备工作

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 添加beanPostProcessor,ApplicationContextAwareProcessor此类用来完成某些Aware对象的注入beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 设置要忽略自动装配的接口,很多同学理解不了为什么此处要对这些接口进行忽略,原因非常简单,这些接口的实现是由容器通过set方法进行注入的,// 所以在使用autowire进行注入的时候需要将这些接口进行忽略beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);}

看下ApplicationContextAwareProcessor这个类:

/*** 接口beanPostProcessor规定的方法,会在bean创建时,实例化后,初始化前,对bean对象应用* @param bean the new bean instance* @param beanName the name of the bean* @return* @throws BeansException*/@Override@Nullablepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){return bean;}AccessControlContext acc = null;if (System.getSecurityManager() != null) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}if (acc != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {// 检测bean上是否实现了某个aware接口,有的话进行相关的调用invokeAwareInterfaces(bean);return null;}, acc);}else {invokeAwareInterfaces(bean);}return bean;}

在这个类postProcessBeforeInitialization(Object bean, String beanName)这个方法内部会调用invokeAwareInterfaces(Object bean) 这个方法,判断bean的类型是属于哪一个xxxAware接口然后执行对应的setXXX()方法,至此和前边实现ApplicationContextAware接口重写setApplicationContext()方法串起来了,在哪里调用setApplicationContext方法完成。

/*** 如果某个bean实现了某个aware接口,给指定的bean设置相应的属性值** @param bean*/private void invokeAwareInterfaces(Object bean) {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);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}}

还有一个问题,ApplicationContextAwareProcessor这个类的postProcessBeforeInitialization(Object bean, String beanName) 方法什么时候在哪里进行调用呢?这个类实现了BeanPostProcessor这个接口

/*** bean的后置处理器接口,在依赖注入的初始化方法前后进行调用*/
public interface BeanPostProcessor {/*** 初始化方法调用前要进行的处理逻辑*/@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}/*** 在初始化方法指定后要进行的处理逻辑*/@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}

接下来看实现了BeanPostProcessor 这个接口的实现类在哪里会被触发调用里面的postProcessBeforeInitialization方法!!!!
通过看调用链路,下面是整个过程是在完成实例化,属性填充,执行初始化的时候在initializeBean方法调用 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
在这里插入图片描述
applyBeanPostProcessorsBeforeInitialization细节,对实现BeanPostProcessor 的类进行调用postProcessBeforeInitialization这个方法,这里会调用到ApplicationContextAwareProcessor的postProcessBeforeInitialization方法来对invokeAwareInterfaces实现Aware接口的类进行set操作

	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {//初始化返回结果为existingBeanObject result = existingBean;//遍历 该工厂创建的bean的BeanPostProcessors列表for (BeanPostProcessor processor : getBeanPostProcessors()) {// postProcessBeforeInitialization:在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法)// 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。// 默认实现按原样返回给定的 BeanObject current = processor.postProcessBeforeInitialization(result, beanName);// 如果 current为nullif (current == null) {//直接返回result,中断其后续的BeanPostProcessor处理return result;}//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装result = current;}//返回经过所有BeanPostProcess对象的后置处理的层层包装后的resultreturn result;}

同时,在完成实例化,属性填充,执行初始化的时候在initializeBean方法调用 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);将BeanPostProcessors应用到给定的现有Bean实例,调用它们的postProcessAfterInitialization方法。

@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {//初始化结果对象为result,默认引用existingBeanObject result = existingBean;//遍历该工厂创建的bean的BeanPostProcessors列表for (BeanPostProcessor processor : getBeanPostProcessors()) {//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装Object current = processor.postProcessAfterInitialization(result, beanName);//一般processor对不感兴趣的bean会回调直接返回result,使其能继续回调后续的BeanPostProcessor;// 但有些processor会返回null来中断其后续的BeanPostProcessor// 如果current为nullif (current == null) {//直接返回result,中断其后续的BeanPostProcessor处理return result;}//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装result = current;}//返回经过所有BeanPostProcess对象的后置处理的层层包装后的resultreturn result;}

至此,BeanPostProcessor接口的调用以及实现xxxAware的类的调用使用处理过程讲解结束

    初始化方法调用前要进行的处理逻辑default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}在初始化方法指定后要进行的处理逻辑default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com