上一節講到bean初始化方法initializeBean方法的第一步,invokeAwareMethods。
這節將初始化bean的第二步,applyBeanPostProcessorsBeforeInitialization方法
看代碼實現:
遍歷beanFactory裏面的beanPostProcessor,執行postProcessBeforeInitialization方法,
/**
* factory的回調,允許用戶自定義bean
* Factory hook that allows for custom modification of new bean instances,
* e.g. checking for marker interfaces or wrapping them with proxies.
* applicationContext 可以自己注入新的beanPostProcessor用來改造bean
* <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.
* 一般是在postProcessAfterInitiazation方法中使用代理包裝bean
* <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}.
*/
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.
*調用初始化前處理
*/
@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.
* 調用初始化後處理
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
看簡單的實現用例:
public class BeanInitializationDemo implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof UserHolder){
UserHolder userHolder = (UserHolder) bean;
System.out.println("初始化前調用 PostProcessorBeforeInitialiation");
userHolder.setDescript("我經歷過了postProcessBeforeInitialization");
}
return bean;
}
}
注意:beanFactory的例子中只能手動添加BeanPostProcessor。
public class BeanLifyCycleDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// beanPostProcessor只能手動添加到beanFactory,不像applicationContext可以自己修改beanfactory的BeanPostProcessor
beanFactory.addBeanPostProcessor(new BeanInitializationDemo());
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions("META-INF/dependency-lookup-context.xml");
beanFactory.addBeanPostProcessor(new BeanInstantiaitionAwareImpl());
UserHolder userHolder = (UserHolder)beanFactory.getBean("userHolder");
System.out.println(userHolder);
}
}
看輸出:
ApplicationContext的例子
public class BeanLifeCycleInApplicationContextDemo {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("META-INF/dependency-lookup-context.xml");
applicationContext.refresh();
applicationContext.getBean(UserHolder.class);
applicationContext.close();
}
}
xml:
輸出: