(十三)生命周期-BeanPostProcessor后置处理器

结论先行

通过实现BeanPostProcessor接口,并实现postProcessBeforeInitialization和postProcessAfterInitialization方法,可以自定义bean初始化前后的逻辑

BeanPostProcessor实现类定义

package com.ouyangxizhu.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

/**
 * 后置处理器:初始化前后进行处理工作
 * 将后置处理器加入到容器中
 *
 * @author lfy
 */
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO Auto-generated method stub
		System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
		return bean;
	}

}

配置类

package com.ouyangxizhu.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.ouyangxizhu.bean")
public class MainConfigBeanPostProcessor {
}

启动类

package com.ouyangxizhu;

import com.ouyangxizhu.config.MainConfigBeanPostProcessor;
import com.ouyangxizhu.config.MainConfigInitializingBeanDisposableBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTestBeanPostProcessor {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfigBeanPostProcessor.class);
        context.close();
    }
}

结果

八月 04, 2020 10:42:56 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0: startup date [Tue Aug 04 22:42:56 CST 2020]; root of context hierarchy
postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerProcessor=>org.springframework.context.event.EventListenerMethodProcessor@149494d8
postProcessAfterInitialization...org.springframework.context.event.internalEventListenerProcessor=>org.springframework.context.event.EventListenerMethodProcessor@149494d8
postProcessBeforeInitialization...org.springframework.context.event.internalEventListenerFactory=>org.springframework.context.event.DefaultEventListenerFactory@646007f4
postProcessAfterInitialization...org.springframework.context.event.internalEventListenerFactory=>org.springframework.context.event.DefaultEventListenerFactory@646007f4
postProcessBeforeInitialization...mainConfigBeanPostProcessor=>com.ouyangxizhu.config.MainConfigBeanPostProcessor$$EnhancerBySpringCGLIB$$b41bc1c4@481a15ff
postProcessAfterInitialization...mainConfigBeanPostProcessor=>com.ouyangxizhu.config.MainConfigBeanPostProcessor$$EnhancerBySpringCGLIB$$b41bc1c4@481a15ff
cat..............constructor
postProcessBeforeInitialization...cat=>com.ouyangxizhu.bean.Cat@545997b1
cat...............init
postProcessAfterInitialization...cat=>com.ouyangxizhu.bean.Cat@545997b1
八月 04, 2020 10:42:57 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext doClose
信息: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0: startup date [Tue Aug 04 22:42:56 CST 2020]; root of context hierarchy
cat..............destroy

Process finished with exit code 0

原理

1.在postProcessBeforeInitialization和postProcessAfterInitialization方法前面分别打一个断点,以debug方式运行启动类
2.进入到postProcessBeforeInitialization方法中,在左下角可以查看调用栈,调用栈如下,如果没有这么详细,可以点击图中右上角的按钮(下面内容自己debug看)
在这里插入图片描述
org.springframework.context.annotation.AnnotationConfigApplicationContext
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
org.springframework.beans.factory.ObjectFactory#getObject
org.springframework.beans.factory.support.AbstractBeanFactory#createBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
3. 原理

遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,
  一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
  
  BeanPostProcessor原理
  populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
  initializeBean
  {
  applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
  applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }

BeanValidationPostProcessor

给javaBean复制以后做校验工作,执行org.springframework.validation.beanvalidation.BeanValidationPostProcessor#doValidate这个方法做校验

InitDestroyAnnotationBeanPostProcessor

处理@PostConstruct和@PreDestroy注解
这个可以在相应的初始化方法打一个断点,debug运行进到断点之后看调用栈

@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	//生命周期注解信息
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
	//调用初始化方法
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
		}
		return bean;
	}
	public void invokeInitMethods(Object target, String beanName) throws Throwable {
		Collection<LifecycleElement> initMethodsToIterate =
				(this.checkedInitMethods != null ? this.checkedInitMethods : this.initMethods);
		if (!initMethodsToIterate.isEmpty()) {
			boolean debug = logger.isDebugEnabled();
			for (LifecycleElement element : initMethodsToIterate) {
				if (debug) {
					logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());
				}
				//反射调用初始化方法
				element.invoke(target);
			}
		}
	}

AutowiredAnnotationBeanPostProcessor

处理@Autowired注解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值