总结Spring框架扩展点(二)bean生命周期中的扩展点(持续更新中...)

面向业务开发的时候,程序员需要明白业务的逻辑,并设计代码结构。而在进行中间件开发的时候,则需要明白框架的逻辑,进行开发。

所以要开发提供给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设置的方法

    如果上述方法都存在的话,执行顺序是:

  1. postProcessBeforeInitialization
  2. afterPropertiesSet
  3. init-method
  4. 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指定的方法。

 

 

一个完整的例子:

https://blog.csdn.net/abw986810159/article/details/61196972

https://www.cnblogs.com/sishang/p/6588542.html

 

a) DestructionAwareBeanPostProcessor

b) InstantiationAwareBeanPostProcessor

c) SmartInstantiationAwareBeanPostProcessor

d) MergedBeanDefinitionPostProcessor

 

 

总结:

 

等待补充

 

 

SmartLifecycle

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值