面向业务开发的时候,程序员需要明白业务的逻辑,并设计代码结构。而在进行中间件开发的时候,则需要明白框架的逻辑,进行开发。
所以要开发提供给spring的中间件,需要知道spring中有哪些扩展点,好在对应的地方插入我们的功能。
1. Spring容器初始化bean大致过程
1. 定义bean标签
2. 将bean标签解析成BeanDefinition
3. 调用构造方法实例化(IOC):
4. 属性值得依赖注入(DI)
2. BeanFactory构造阶段
1.1 NamespaceHandler
3. ApplicationContext构造阶段
3.1 BeanFactoryPostProcessor
说明:
顾名思义,是BeanFactory的后置处理器,处理的对象是BeanFactory
执行时间:
bean factory已经被standard initialization了
所有的bean definitions已经被家在到bean factory中了
但是还没有实例化任何的bean,bean的构造函数都没被执行
注册方法:
要使用BeanPostProcessor回调,就必须先在容器中注册实现该接口的类,那么如何注册呢?BeanFactory和ApplicationContext容器的注册方式不大一样:若使用BeanFactory,则必须要显示的调用其addBeanPostProcessor()方法进行注册,参数为BeanPostProcessor实现类的实例;如果是使用ApplicationContext.xml,那么容器会在配置文件在中自动寻找实现了BeanPostProcessor接口的Bean,然后自动注册,我们要做的只是配置一个BeanPostProcessor实现类的Bean就可以了。
一般用途:
获取相关Bean的bean definition,并修改bean definition
例如:
- 给属性赋值,修改属性值
- 可以把bean的scope从singleton改为prototype,也可以把property的值给修改掉。
- 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序
spring内置的BeanFactoryPostProcessor实现类:
- org.springframework.beans.factory.config.PropertyPlaceholderConfigurer:属性占位符配置
- org.springframework.beans.factory.config.PropertyOverrideConfigurer:
- org.springframework.beans.factory.config.CustomEditorConfigurer:用来注册自定义的属性编辑器
正式应用:
比如笔者使用的某款知名内部RPC框架中,在Client端,因为需要被代理的类并没有真正的实现类,也就不会有对应的bean注册到容器里,所以Client端就需要在BeanFactoryPostProcessor这个阶段,通过AnnotationUtils扫描注解,从而给通过注解标记的需要代理的类,创建一个代理bean,并手动调用registry.registerBeanDefinition注册到容器里的。而对应的,RPC框架的Server端,只需要在下面BeanPostProcessor处理就可以了。
3.2 BeanPostProcessor
说明:
顾名思义,是Bean的后置处理器,处理的对象是Bean
执行时间:
bean被spring容器实例化之后,即构造函数已经被执行
bean的set方法被调用注入属性值之后
在执行bean的初始化方法的前后。这里说的初始化方法,指的是下面两种:
- bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
- 在bean定义的时候,通过init-method设置的方法
如果上述方法都存在的话,执行顺序是:
- postProcessBeforeInitialization
- afterPropertiesSet
- init-method
- postProcessAfterInitialization
注册方法:
跟BeanPostProcessor一样,ApplicationContext也能自动检测和调用容器中的BeanFactoryPostProcessor。
一般用途:
例如:给bean添加动态代理
spring内置的BeanPostProcessor实现类:
- org.springframework.context.annotation.CommonAnnotationBeanPostProcessor:支持@Resource注解的注入
- org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor:支持@Required注解的注入
- org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor:支持@Autowired注解的注入
- org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor:支持@PersistenceUnit和@PersistenceContext注解的注入
- org.springframework.context.support.ApplicationContextAwareProcessor:用来为bean注入ApplicationContext等容器对象
3.3 系统如何调用这几个方法的
在使用ApplicationContext启动spring容器的时候,在AbstractApplicationContext.refresh()方法中,完成相关初始化工作:
首先是BeanFactoryPostProcessor钩子:
在第5步invokeBeanFactoryPostProcessors方法中,调用了BeanFactoryPostProcessor.postProcessBeanFactory方法,相关源码如下:
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// Invoke factory processors registered with the context instance.
for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
factoryProcessor.postProcessBeanFactory(beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List priorityOrderedPostProcessors = new ArrayList();
List orderedPostProcessorNames = new ArrayList();
List nonOrderedPostProcessorNames = new ArrayList();
for (int i = 0; i < postProcessorNames.length; i++) {
if (isTypeMatch(postProcessorNames[i], PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(postProcessorNames[i]));
}
else if (isTypeMatch(postProcessorNames[i], Ordered.class)) {
orderedPostProcessorNames.add(postProcessorNames[i]);
}
else {
nonOrderedPostProcessorNames.add(postProcessorNames[i]);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
Collections.sort(priorityOrderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List orderedPostProcessors = new ArrayList();
for (Iterator it = orderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
orderedPostProcessors.add(getBean(postProcessorName));
}
Collections.sort(orderedPostProcessors, new OrderComparator());
invokeBeanFactoryPostProcessors(beanFactory, orderedPostProcessors);
// Finally, invoke all other BeanFactoryPostProcessors.
List nonOrderedPostProcessors = new ArrayList();
for (Iterator it = nonOrderedPostProcessorNames.iterator(); it.hasNext();) {
String postProcessorName = (String) it.next();
nonOrderedPostProcessors.add(getBean(postProcessorName));
}
invokeBeanFactoryPostProcessors(beanFactory, nonOrderedPostProcessors);
}
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {
for (Iterator it = postProcessors.iterator(); it.hasNext();) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor) it.next();
postProcessor.postProcessBeanFactory(beanFactory);
}
}
上面的代码中,首先通过beanFactory.getBeanNamesForType获取spring配置文件中定义的,所有实现BeanFactoryPostProcessor接口的bean,然后根据优先级进行排序,之后对于每个BeanFactoryPostProcessor,调用postProcessBeanFactory方法。
然后是BeanPostProcessor钩子:
第一种情况,对于prototype类型的bean,第6步中,调用registerBeanPostProcessors方法,注册所有实现BeanPostProcessor接口的bean。然后等到程序执行该bean的getBean方法初始化的时候执行对应的BeanPostProcessor方法。
第二种情况,对于singleton类型的bean,并且不是抽象类,也不延迟初始化,则在第11步中,通过finishBeanFactoryInitialization方法,调用getBean方法来实例化bean,从而直接执行BeanPostProcessor方法
可以看到,BeanPostProcessor钩子都是在bean被getBean方法初始化的时候被执行,只不过getBean方法被执行的时间不同。我们接下来看看getBean方法做了什么:
getBean方法最终是通过调用AbstractAutowireCapableBeanFactory.doCreateBean方法来执行初始化的,该方法的实现如下:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
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);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set actualDependentBeans = new LinkedHashSet(dependentBeans.length);
for (int i = 0; i < dependentBeans.length; i++) {
String dependentBean = dependentBeans[i];
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
我们可以看到,getBean方法中,首先调用createBeanInstance方法,创建bean实例对象(这个时候执行bean的构造方法),然后调用populateBean方法,对bean进行填充,注入相关依赖,之后再调用方法initializeBean,进行相关初始化工作,initializeBean方法的实现如下:
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
从上面的实现可以看出,initializeBean先调用applyBeanPostProcessorsBeforeInitialization方法,执行每个BeanPostProcessor的postProcessBeforeInitialization,然后调用invokeInitMethods方法,执行bean的初始化方法,最后调用applyBeanPostProcessorsAfterInitialization方法,执行每个BeanPostProcessor的postProcessAfterInitialization方法。
postProcessBeforeInitialization,applyBeanPostProcessorsAfterInitialization,invokeInitMethods这三个方法的实现如下:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
}
return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
result = beanProcessor.postProcessAfterInitialization(result, beanName);
}
return result;
}
protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
((InitializingBean) bean).afterPropertiesSet();
}
String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
}
}
重点看一下invokeInitMethods方法,里面先执行afterPropertiesSet方法,然后再通过反射,执行init-method指定的方法。
一个完整的例子:
a) DestructionAwareBeanPostProcessor
b) InstantiationAwareBeanPostProcessor
c) SmartInstantiationAwareBeanPostProcessor
d) MergedBeanDefinitionPostProcessor
总结:
等待补充
SmartLifecycle