spring注解驱动系列--Bean生命周期二

本文详细解析了Spring框架中BeanPostProcessor在bean生命周期中的执行流程,重点介绍了applyBeanPostProcessorsBeforeInitialization和postProcessAfterInitialization方法,以及AsyncAnnotationBeanPostProcessor、ApplicationContextAwareProcessor、BeanValidationPostProcessor和InitDestroyAnnotationBeanPostProcessor等关键实现类的作用。
摘要由CSDN通过智能技术生成

一、BeanPostProcessor执行流程

在bean生命周期中,当bean对象创建完了之后,会调用populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值,之后会调用initializeBean方法进行初始化,而BeanPostProcessor中的postProcessBeforeInitialization与postProcessAfterInitialization方法就是在initializeBean中执行的。

 populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
  initializeBean
 {
  applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
 invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
 }

 

一、  initializeBean函数

 initializeBean函数中将会执行初始化前置操作--》初始化操作--》初始化后置操作

 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
        // 初始化前置操作
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
        // 初始化操作
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
        // 初始化后置操作
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

二、applyBeanPostProcessorsBeforeInitialization函数

 遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
        }

        return result;
    }

二、BeanPostProcessor主要实现类

一、AsyncAnnotationBeanPostProcessor

@Async注解起作用是靠AsyncAnnotationBeanPostProcessor这个类实现的,这个类会处理@Async注解。

AsyncAnnotationBeanPostProcessor这个类的对象是由@EnableAsync注解放入到Spring容器的,这也是为什么需要使用@EnableAsync注解来激活让@Async注解起作用的根本原因。

这个类实现了 BeanPostProcessor 接口,实现了 postProcessAfterInitialization 方法,是在其父类AbstractAdvisingBeanPostProcessor 中实现的,也就是说当Bean的初始化阶段完成之后会回调 AsyncAnnotationBeanPostProcessor 的 postProcessAfterInitialization 方法。之所以会回调,是因为在Bean的生命周期中,当Bean初始化完成之后,会回调所有的 BeanPostProcessor 的 postProcessAfterInitialization 方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
         Object current = processor.postProcessAfterInitialization(result, beanName);
         if (current == null) {
            return result;
         }
         result = current;
     }
    return result;
}

 AsyncAnnotationBeanPostProcessor 对于 postProcessAfterInitialization 方法实现:

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
    if (this.advisor == null || bean instanceof AopInfrastructureBean) {
   // Ignore AOP infrastructure such as scoped proxies.
        return bean;
    }

    if (bean instanceof Advised) {
       Advised advised = (Advised) bean;
       if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
           // Add our local Advisor to the existing proxy's Advisor chain...
           if (this.beforeExistingAdvisors) {
              advised.addAdvisor(0, this.advisor);
           }
           else {
              advised.addAdvisor(this.advisor);
           }
           return bean;
        }
     }

     if (isEligible(bean, beanName)) {
        ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
        if (!proxyFactory.isProxyTargetClass()) {
           evaluateProxyInterfaces(bean.getClass(), proxyFactory);
        }
        proxyFactory.addAdvisor(this.advisor);
        customizeProxyFactory(proxyFactory);
        return proxyFactory.getProxy(getProxyClassLoader());
     }

     // No proxy needed.
     return bean;
}

该方法的主要作用是用来对方法入参的对象进行动态代理的,当入参的对象的类加了@Async注解,那么这个方法就会对这个对象进行动态代理,最后会返回入参对象的代理对象出去。至于如何判断方法有没有加@Async注解,是靠 isEligible(bean, beanName) 来判断的。

也就是当Bean创建过程中初始化阶段完成之后,会调用 AsyncAnnotationBeanPostProcessor 的 postProcessAfterInitialization 的方法,对加了@Async注解的类的对象进行动态代理,然后返回一个代理对象回去。

二、ApplicationContextAwareProcessor

主要作用是用于获取ioc容器对象,通过ios容器对象获取想要的容器内对象或者是相关功能。

例如:

@Component
public class SpringContextUtil implements ApplicationContextAware {

    // Spring应用上下文环境
    private static ApplicationContext context;

    /**
     * 实现ApplicationContextAware接口的回调方法。设置上下文环境
     *
     * @param applicationContext
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
        SpringContextUtil.context = applicationContext;
    }

    /**
     * @return ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return context;
    }

    public static Object getBean(String name) throws BeansException {
        return context.getBean(name);
    }
 
    public static <T> T getBean(Class<T> clazz) {
        return this.context.getBean(clazz);
    }
 
    public static <T> T getBean(String beanName, Class<T> clazz) {
        try {
            return this.context.getBean(beanName, clazz);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

 三、BeanValidationPostProcessor

主要用来进行数据校验的,例如从前端传入进接口的数据,进行校验。

四、InitDestroyAnnotationBeanPostProcessor

主要是用于实现 @PostConstruct注解以及@PreDestroy注解

 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 获取到生命周期注解,例如@PostConstruct注解以及@PreDestroy注解
        LifecycleMetadata metadata = this.findLifecycleMetadata(bean.getClass());

        try {
            // 执行注解下的方法
            metadata.invokeInitMethods(bean, beanName);
            return bean;
        } catch (InvocationTargetException var5) {
            throw new BeanCreationException(beanName, "Invocation of init method failed", var5.getTargetException());
        } catch (Throwable var6) {
            throw new BeanCreationException(beanName, "Failed to invoke init method", var6);
        }
    }
下面函数invokeInitMethods主要是执行生命周期注解下的方法,通过反射进行执行。主要是element.invoke(target)进行执行
 public void invokeInitMethods(Object target, String beanName) throws Throwable {
            Collection<LifecycleElement> checkedInitMethods = this.checkedInitMethods;
            Collection<LifecycleElement> initMethodsToIterate = checkedInitMethods != null ? checkedInitMethods : this.initMethods;
            LifecycleElement element;
            if (!((Collection)initMethodsToIterate).isEmpty()) {
                for(Iterator var5 = ((Collection)initMethodsToIterate).iterator(); var5.hasNext(); element.invoke(target)) {
                    element = (LifecycleElement)var5.next();
                    if (InitDestroyAnnotationBeanPostProcessor.this.logger.isTraceEnabled()) {
                        InitDestroyAnnotationBeanPostProcessor.this.logger.trace("Invoking init method on bean '" + beanName + "': " + element.getMethod());
                    }
                }
            }

        }

 五、AutowiredAnnotationBeanPostProcessor

对象创建完之后,将会对标注了@Autowired注解的属性进行赋值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值