spring源码分析系列 (2) spring拓展接口BeanPostProcessor
Spring更多分析--spring源码分析系列
主要分析内容:
一、BeanPostProcessor简述与demo示例
二、BeanPostProcessor源码分析:注册时机和触发点
(源码基于spring 5.1.3.RELEASE分析)
一、BeanPostProcessor简述与demo示例
BeanPostProcessor是spring非常重要的拓展接口,例如aop通过拓展接口生产代理bean等。接口有两个方法:
/**
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
*
* <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
* bean definitions and apply them to any beans subsequently created.
* Plain bean factories allow for programmatic registration of post-processors,
* applying to all beans created through this factory.
*
* <p>Typically, post-processors that populate beans via marker interfaces
* or the like will implement {@link #postProcessBeforeInitialization},
* while post-processors that wrap beans with proxies will normally
* implement {@link #postProcessAfterInitialization}.
*
* @author Juergen Hoeller
* @since 10.10.2003
* @see InstantiationAwareBeanPostProcessor
* @see DestructionAwareBeanPostProcessor
* @see ConfigurableBeanFactory#addBeanPostProcessor
* @see BeanFactoryPostProcessor
*/
public interface BeanPostProcessor { /**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
} /**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
} }
以上为spring原始接口,这里说明一下:
- ApplicationContext类型的容器会自动发现和注册该类型的bean,通过BeanPostProcessor可以对bean进行定制化,接口作用域是所有bean创建。
- postProcessBeforeInitialization触发时机在bean实例化(Instantiation)之后,所有初始化(Initialization)动作(包括 InitializingBean#afterPrpertiesSet() 和 定制化init-method())以前。
- postProcessAfterInitialization触发时机在bean实例化(Instantiation)之后,所有初始化(Initialization)动作(包括 InitializingBean#afterPrpertiesSet() 和 定制化init-method())以后。同时还会在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 和 FactoryBean(bean工厂)获得bean时候调用。这个也是重要的点,放在往后的博客中阐述。
由于ApplicationContext可以自动发现并注册BeanPostProcessor,如下使用ApplicationContext类型容器实现一个简单demo。 对应的demo代码可参考: https://gitee.com/zhouxiaoxing91/learning-src/tree/master
public class BeanPostProcessorTest { private ApplicationContext applicationContext ; @Before
public void beforeApplicationContext(){
/**
* ApplicationContext 自动注册 BeanPostProcessor
* 不需要手动注册
* */
applicationContext = new ClassPathXmlApplicationContext("ioc-beanPostProcessor.xml") ;
} @Test
public void test(){
Bean bean = applicationContext.getBean("bean", Bean.class) ;
System.out.println(bean);
} @After
public void after(){
((ClassPathXmlApplicationContext)applicationContext).close();
}
}
BeanPostProcessorTest.java
public class Bean { public Bean(){ } public Bean(String name){
System.out.println("构造函数被调用啦");
this.name = name ;
} private String name ; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Bean{" +
"name='" + name + '\'' +
'}';
}
}
Bean.java
public class LogicBeanPostProcessor implements BeanPostProcessor { @Nullable
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = " + beanName);
return bean;
} @Nullable
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = " + beanName);
return bean;
}
}
LogicBeanPostProcessor.java
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="bean" class="com.nancy.ioc.Bean">
<constructor-arg name="name" value="zhouxiaoxing"/>
</bean> <bean id="logicBeanPostProcessor" class="com.nancy.ioc.BeanPostProcessor.LogicBeanPostProcessor"/>
</beans>
ioc-beanPostProcessor.xml
运行结果符合以上的结论:
构造函数被调用啦
LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = bean
LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = bean
Bean{name='zhouxiaoxing'}
提出两个疑问:
1、在ApplicationContext容器中何时注册BeanPostProcessor接口 ?
二、BeanPostProcessor源码分析:注册时机和触发点
1、注册BeanPostProcessor
在AbstractApplicationContext容器启动的refresh()会注册BeanPostProcessor,源码如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh(); // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory); try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation.
// 注册BeanPostProcessor 在bean创建的时候进行拦截
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource(); // Initialize event multicaster for this context.
initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses.
onRefresh(); // Check for listener beans and register them.
registerListeners(); // Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event.
finishRefresh();
} catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
} // Destroy already created singletons to avoid dangling resources.
destroyBeans(); // Reset 'active' flag.
cancelRefresh(ex); // Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
} ...... /**
* Instantiate and invoke all registered BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
跟进PostProcessorRegistrationDelegate.registerBeanPostProcessors
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { /**
* 此时bean的定义加载已经完成,但是还没有实例化。 获得所有BeanPostProcessor bean对应的beanName
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); /**
* 注册日志BeanPostProcessor, 检测注册的bean是否为spring基础服务类并打印日志
*/
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); /**
* 当有注册多个BeanPostProcessor接口时会按顺序进行,即 实现PriorityOrdered->实现Ordered->普通类型接口->内部系统MergedBeanDefinitionPostProcessor
*/
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { /**
* 通过beanFactory.getBean(), 将会提前初始化BeanPostProcessor类型实例
*/
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
} // First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors); /**
* ApplicationListener探测器,当bean实现ApplicationListener接口时自动注册监听
*/
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
} /**
* 按照给定Ordered的顺序排序
*/
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
comparatorToUse = OrderComparator.INSTANCE;
}
postProcessors.sort(comparatorToUse);
} /**
* Register the given BeanPostProcessor beans.
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
跟进AbstractBeanFactory#addBeanPostProcessor
/** BeanPostProcessors to apply in createBean. */
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>(); /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */
private volatile boolean hasInstantiationAwareBeanPostProcessors; /** Indicates whether any DestructionAwareBeanPostProcessors have been registered. */
private volatile boolean hasDestructionAwareBeanPostProcessors; /**
* 所有的BeanPostProcessor接口实例保存于CopyOnWriteArrayList中
* 1、一个实例只注册一次
* 2、通过hasInstantiationAwareBeanPostProcessors设置,判定是否存在InstantiationAwareBeanPostProcessor接口实例,为后续执行做判断
* 3、通过hasDestructionAwareBeanPostProcessors设置,判定是否存在DestructionAwareBeanPostProcessor接口实例,为后续执行做判断
*/
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
修改上述demo中LogicBeanPostProcessor.java文件,并debug模式查看:
public class LogicBeanPostProcessor implements BeanPostProcessor { public LogicBeanPostProcessor(){
System.out.println("LogicBeanPostProcessor 被 beanFactory.getBean() 提前初始化");
} @Nullable
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = " + beanName);
return bean;
} @Nullable
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = " + beanName);
return bean;
}
}
查看PostProcessorRegistrationDelegate#registerBeanPostProcessors,注册一个普通BeanPostProcessor -> logicBeanPostProcessor
最后运行结果:
LogicBeanPostProcessor 被 beanFactory.getBean() 提前初始化
构造函数被调用啦
LogicBeanPostProcessor.postProcessBeforeInitialization 执行啦 beanName = bean
LogicBeanPostProcessor.postProcessAfterInitialization 执行啦 beanName = bean
Bean{name='zhouxiaoxing'}
总结如下:
(1)、BeanPostProcessor注册的入口在AbstractApplicationContext容器启动的refresh()的AbstractApplicationContext#registerBeanPostProcessors。
(2)、AbstractApplicationContext进而委派PostProcessorRegistrationDelegate#registerBeanPostProcessors实现注册。
(3)、当有注册多个BeanPostProcessor接口时会按顺序进行,即 实现PriorityOrdered->实现Ordered->普通类型接口->内部系统MergedBeanDefinitionPostProcessor。而同种类型也会进行排序,按顺序注册。
(4)、BeanPostProcessor类型实例会通过BeanFactory#getBean()提前初始化。
2、触发BeanPostProcessor方法
触发BeanPostProcessor有很多入口,首先分析几个入口后续的再补上。
触发(1)AbstractAutowireCapableBeanFactory#createBean 中:
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException { if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} // Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
} try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
} try {
// bean 创建
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
} /**
* Actually create the specified bean. Pre-creation processing has already happened
* at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
* <p>Differentiates between default bean instantiation, use of a
* factory method, and autowiring a constructor.
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException { // Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
} // 省略...... // Initialize the bean instance.
Object exposedObject = bean;
try {
// 根据加载到的bean definition给 bean赋值
populateBean(beanName, mbd, instanceWrapper);
// 调用bean初始化方法
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
} // 省略...... return exposedObject;
}
跟进AbstractAutowireCapableBeanFactory#initializeBean方法:
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 1、工厂factory类 接口回调
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2、BeanPostProcessor前置执行
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
// 3、InitializingBean接口方法 or 自定义 init method 执行
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 4、BeanPostProcessor后置执行
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
} return wrappedBean;
}
对应回调方法:
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
} /**
* Give a bean a chance to react now all its properties are set,
* and a chance to know about its owning bean factory (this object).
* This means checking whether the bean implements InitializingBean or defines
* a custom init method, and invoking the necessary callback(s) if it does.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the merged bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @throws Throwable if thrown by init methods or by the invocation process
* @see #invokeCustomInitMethod
*/
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
} if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
} @Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
} @Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException { Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
initializeBean对应的方法
总结如下:
(1.1)、由此可见BeanPostProcessor的一个触发入口在AbstractAutowireCapableBeanFactory#createBean,最终至AbstractAutowireCapableBeanFactory#initializeBean。
(1.2)、AbstractAutowireCapableBeanFactory#initializeBean不但会触发BeanPostProcessor回掉方法,并且还会按顺序执行bean生命周期:
- factory类型接口(BeanNameAware#setBeanName)
- factory类型接口(BeanClassLoaderAware#setBeanClassLoader)
- factory类型接口(BeanFactoryAware#setBeanFactory)
- BeanPostProcessor#postProcessBeforeInitialization
- InitializingBean和自定义的init-method
- BeanPostProcessor#postProcessAfterInitialization
触发(2)FactoryBeanRegistrySupport(后续补上)
spring源码分析系列 (2) spring拓展接口BeanPostProcessor的更多相关文章
- spring源码分析系列 (3) spring拓展接口InstantiationAwareBeanPostProcessor
更多文章点击--spring源码分析系列 主要分析内容: 一.InstantiationAwareBeanPostProcessor简述与demo示例 二.InstantiationAwareBean ...
- spring源码分析系列 (5) spring BeanFactoryPostProcessor拓展类PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer解析
更多文章点击--spring源码分析系列 主要分析内容: 1.拓展类简述: 拓展类使用demo和自定义替换符号 2.继承图UML解析和源码分析 (源码基于spring 5.1.3.RELEASE分析) ...
- spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
更多文章点击--spring源码分析系列 主要分析内容: 一.BeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessor简述与demo示例 ...
- 【Spring源码分析系列】ApplicationContext 相关接口架构分析
[原创文章,转载请注明出处][本文地址]http://www.cnblogs.com/zffenger/p/5813470.html 在使用Spring的时候,我们经常需要先得到一个Applicati ...
- spring源码分析系列
spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor.BeanDefinitionRegistryPostProcessor spring源码分析系列 ...
- spring源码分析系列 (8) FactoryBean工厂类机制
更多文章点击--spring源码分析系列 1.FactoryBean设计目的以及使用 2.FactoryBean工厂类机制运行机制分析 1.FactoryBean设计目的以及使用 FactoryBea ...
- spring源码分析系列 (15) 设计模式解析
spring是目前使用最为广泛的Java框架之一.虽然spring最为核心是IOC和AOP,其中代码实现中很多设计模式得以应用,代码看起来简洁流畅,在日常的软件设计中很值得借鉴.以下是对一些设计模式的 ...
- 【Spring源码分析系列】启动component-scan类扫描加载过程
原文地址:http://blog.csdn.net/xieyuooo/article/details/9089441/ 在spring 3.0以上大家都一般会配置一个Servelet,如下所示: &l ...
- spring源码分析系列3:BeanFactory核心容器的研究
目录 @(spring源码分析系列3:核心容器的研究) 在讲容器之前,再明确一下知识点. BeanDefinition是Bean在容器的描述.BeanDefinition与Bean不是一个东西. Be ...
随机推荐
- Android 图片平铺效果
我们大家都看过平铺的效果,那么我们都是怎么样才能实现的那,我们其实主要用到的就是api,我们一开始new一个bitmap,就可以了,但是,大家都没有想过,我们还可以用什么方法来做这个事情那,那么我们就 ...
- 关卡得分(if 嵌套for)与(for嵌套if)
- python----多继承C3算法
https://blog.csdn.net/fmblzf/article/details/52512145
- python 全栈开发,Day10(动态参数,命名空间,作用域,函数嵌套)
一.动态参数 def func(a,b,c,d,e,f,g): pass func(1,2,3,4,5,6,7) 如果加30个参数呢?有没有万能的参数,可以代表一切参数呢? *args 动态参数,万能 ...
- 扩展方法 C#
“扩展方法使您能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.” 定义和调用扩展方法 定义一个静态类以包含扩展方法. 该类必须对客户端代码可见. 有关可访问性规则 ...
- 传统DOM事件处理程序
传统DOM事件处理程序与比HTML事件处理程序相比,优点:可以将HTML和JS脚本分离. 它的操作形式如下 : <body> <div>传统DOM事件处理程序与比HTML事件处 ...
- 使用拷贝文件测试(BufferedInputStream,FileInputStream)
package com.demo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ja ...
- Python中List的append引用赋值问题处理
Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...
- IE下script标签的readyState属性
在做加载器时遇到一个常见问题,如何判定一个脚本已经执行完毕. "uninitialized" – 原始状态 "loading" – 下载数据中 "lo ...
- asp.net core web项目目录解读
Connected Services 和传统.net web项目相比,它的功能类似于添加webservice或者wcf service的引用.暂时用不到,有兴趣的小伙伴可以深入了解.右键这个目录可以看 ...