Spring 中 Bean 的生命周期
程序员文章站
2022-05-24 18:06:21
...
对beanFactory的修改
实例化BeanFactoryPostProcessor
,实例化前后不会被调用BeanPostProcessor
的方法。
BeanFactoryPostProcessorTest()
BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): void
@Slf4j
@Component
public class BeanFactoryPostProcessorTest implements BeanFactoryPostProcessor {
public BeanFactoryPostProcessorTest() {
log.debug("BeanFactoryPostProcessorTest()");
}
/**
* All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory
* @throws BeansException
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
log.debug("BeanFactoryPostProcessor.postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory): void");
}
}
实例化BeanPostProcessor
BeanPostProcessor
实例化前后不会被调用BeanPostProcessor
的方法。
BeanPostProcessorForPostProcessors()
BeanPostProcessorTest()
InstantiationAwareBeanPostProcessorTest()
@Slf4j
@Component
public class BeanPostProcessorTest implements BeanPostProcessor {
public BeanPostProcessorTest() {
log.debug("BeanPostProcessorTest()");
}
/**
* The bean will already be populated with property values.(属性注入完毕)
* before any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
* The returned bean instance may be a wrapper around the original.
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof BeanTest) {
log.debug("BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName): Object");
}
return bean;
}
/**
* after any bean initialization callbacks (like InitializingBean's {@code afterPropertiesSet} or a custom init-method).
* this callback will be invoked for both the FactoryBean(不是BeanFactory) instance and the objects created by the FactoryBean (as of(自从) Spring 2.0).
*
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof BeanTest) {
log.debug("BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName): Object");
}
return bean;
}
}
@Slf4j
@Component
public class InstantiationAwareBeanPostProcessorTest implements InstantiationAwareBeanPostProcessor {
public InstantiationAwareBeanPostProcessorTest() {
log.debug("InstantiationAwareBeanPostProcessorTest()");
}
/**
* before the target bean creation. The returned bean object may be a proxy to use instead of the target bean, suppressing default creation process of the target bean.
* 可作用于BeanDefinition以及factory-method,If a non-null object is returned by this method, the bean creation process will be short-circuited.(即factory-method也不会被调用)
*
* @param beanClass BeanDefinition的Bean类型或者factory-method的返回值类型
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanClass.equals(BeanTest.class)) {
log.debug("InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName): Object");
}
return null;
}
/**
* after the bean has been instantiated, via a constructor or factory method,
* before Spring property population (from explicit properties or autowiring) occurs.
* This is the ideal callback for performing custom field injection on the given bean instance, right before Spring's autowiring kicks in.
*
* @return {@code true} if properties should be set on the bean; {@code false}
* if property population should be skipped. Normal implementations should return {@code true}.
* Returning {@code false} will also prevent any subsequent(随后的) InstantiationAwareBeanPostProcessor
* instances being invoked on this bean instance.
*/
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (bean instanceof BeanTest) {
log.debug("InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName): boolean");
}
return true;
}
/**
* Post-process *the given property values* before the factory applies them to the given bean, without any need for property descriptors.
* <p>
* Implementations should return {@code null} (the default) if they provide a custom {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.
* In a future version of this interface (with {@link #postProcessPropertyValues} removed), the default implementation will return the given {@code pvs} as-is directly.
*
* @return the actual property values to apply to the given bean (can be the passed-in
* PropertyValues instance), or {@code null} which proceeds with the existing properties
* but specifically continues with a call to {@link #postProcessPropertyValues}
* (requiring initialized {@code PropertyDescriptor}s for the current bean class)
*/
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (bean instanceof BeanTest) {
log.debug("InstantiationAwareBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName): PropertyValues");
}
return null;
}
/**
* 与postProcessProperties相比需要额外的PropertyDescriptor[]参数
* deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
// InstantiationAwareBeanPostProcessor 继承于BeanPostProcessor,在合适的时机如下方法也会被调用
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
@Slf4j
@Component
public class BeanPostProcessorForPostProcessors implements BeanPostProcessor {
public BeanPostProcessorForPostProcessors() {
log.debug("BeanPostProcessorForPostProcessors()");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 并不会作用于这些类
if (bean instanceof BeanFactoryPostProcessor) {
log.debug("before BeanFactoryPostProcessor, beanClass: " + bean.getClass().getName());
} else if (bean instanceof BeanPostProcessor) {
log.debug("before BeanPostProcessor, beanClass: " + bean.getClass().getName());
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 并不会作用于这些类
if (bean instanceof BeanFactoryPostProcessor) {
log.debug("after BeanFactoryPostProcessor, beanClass: " + bean.getClass().getName());
} else if (bean instanceof BeanPostProcessor) {
log.debug("after BeanPostProcessor, beanClass: " + bean.getClass().getName());
}
return bean;
}
}
Bean的生命周期
@Slf4j
public class BeanTest implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean, DisposableBean {
public BeanTest() {
log.debug("constructor");
}
@Autowired
public void setBeanTest(BeanTest beanTest) {
log.debug("BeanTest.setBeanTest(BeanTest beanTest): void");
}
@Override
public void setBeanName(String name) {
log.debug("BeanNameAware.setBeanName(String name): void");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
log.debug("BeanFactoryAware.setBeanFactory(BeanFactory beanFactory): void, factoryClass: " + beanFactory.getClass().getName());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
log.debug("ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext): void, ctxClass: " + applicationContext.getClass().getName());
}
@Override
public void afterPropertiesSet() throws Exception {
log.debug("InitializingBean.afterPropertiesSet(): void");
}
/**
* 通过@Bean的initMethod属性指定
* Not commonly used, given that(考虑到) the method may be called programmatically directly within the body of a Bean-annotated method.
*/
public void initMethod() {
log.debug("init-method");
}
@Override
public void destroy() throws Exception {
log.debug("DisposableBean.destory(): void");
}
/**
* 通过@Bean的destroyMethod属性指定
* a method to call on the bean instance upon closing the application context.
* As a convenience to the user, the container will attempt to infer a destroy method against an object returned from the {@code @Bean} method.
* This 'destroy method inference' is currently limited to detecting only public, no-arg methods named 'close' or 'shutdown'.
* The method may be declared at any level of the inheritance hierarchy and will be detected regardless of the return type of the {@code @Bean} method
* (i.e., detection occurs reflectively against the bean instance itself at creation time).
*/
public void destroyMethod() {
log.debug("destory-method");
}
}
实例化Bean(不包括BeanPostProcessor、BeanFactoryPostProcessor)
实例化相关的三个调用
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(Class<?> beanClass, String beanName): Object
constructor
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(Object bean, String beanName): boolean
属性注入
在设置属性前,可以修改属性值,或者添加删除属性
InstantiationAwareBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName): PropertyValues
属性赋值
BeanTest.setBeanTest(BeanTest beanTest): void
三个Aware接口设置属性
BeanNameAware.setBeanName(String name): void
BeanFactoryAware.setBeanFactory(BeanFactory beanFactory): void, factoryClass: org.springframework.beans.factory.support.DefaultListableBeanFactory
ApplicationContextAware.setApplicationContext(ApplicationContext applicationContext): void, ctxClass: org.springframework.context.annotation.AnnotationConfigApplicationContext
初始化Bean(init-method)
初始化前
- 调用所有的
BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName): Object
InitializingBean.afterPropertiesSet(): void
初始化
init-method
初始化后
- 调用所有的
BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName): Object
t.i.d.springboot.lifecycle.LifeCycleApp : Started LifeCycleApp in 1.184 seconds (JVM running for 2.175)
@ComponentScan(basePackageClasses = LifeCycleApp.class)
public class LifeCycleApp {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
BeanTest beanTest() {
return new BeanTest();
}
public static void main(String[] args) {
new SpringApplicationBuilder(LifeCycleApp.class)
.web(WebApplicationType.NONE)
.run(args);
}
}
销毁Bean
DisposableBean.destory(): void
destory-method