IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

【spring源码分析】IOC容器初始化——查漏补缺(二)

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

前言:在【spring源码分析】IOC容器初始化(八)中多次提到了前置处理与后置处理,本篇文章针对此问题进行分析。Spring对前置处理或后置处理主要通过BeanPostProcessor进行实现。


BeanPostProcessor的作用:在Bean实例化前后,如果需要对Bean进行一些配置、增加一些自己的处理逻辑,则使用BeanPostProcessor。

BeanPostProcessor示例

定义一个类实现BeanPostProcessor接口:

 public class UserDefinedBeanPostProcessor implements BeanPostProcessor {

     @Override
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
         System.out.println("BeanName=" + beanName + " 初始化之前进入");
         if ("beanPostProcessorBase".equals(beanName)) {
             BeanPostProcessorBase processorBase = (BeanPostProcessorBase) bean;
             processorBase.setMsg("Hello BeanPostProcessor!!!!!!!");
         }
         return bean;
     }

     @Override
     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
         System.out.println("BeanName=" + beanName + " 初始化之后进入");
         return bean;
     }

     public void showMsg() {
         System.out.println("BeanPostProcessor Test!!!!!!");
     }
 }

再定义一个基础测试类:

 public class BeanPostProcessorBase {

     private String msg;

     public String getMsg() {
         return msg;
     }

     public void setMsg(String msg) {
         this.msg = msg;
     }
 }

测试方法:

     @Test
     public void beanPostProcessorTest() {
         ApplicationContext context = new ClassPathXmlApplicationContext("com/dev/config/beanpostprocessor/beanpostprocessor.xml");
         BeanPostProcessorBase postProcessor = context.getBean(BeanPostProcessorBase.class);
         System.out.println(postProcessor.getMsg());
     }

运行结果:

108_1.png

分析:

首先必须明确BeanPostProcessor的执行时机:AbstractAutowireCapableBeanFactory#initializeBean方法

 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
         // 安全模式
         if (System.getSecurityManager() != null) {
             AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                 // 激活Aware方法,对特殊bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
                 invokeAwareMethods(beanName, bean);
                 return null;
             }, getAccessControlContext());
         } else {
             //  非安全模式下激活Aware方法,对特殊bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
             invokeAwareMethods(beanName, bean);
         }

         // 后置处理器 before
         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);
         }
         // 后置处理器 after
         if (mbd == null || !mbd.isSynthetic()) {
             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
         }

         return wrappedBean;
     }

分析:

  • 从该函数逻辑可以看出,BeanPostProcessor的执行时机是在bean初始化前后,其实这里也可以看出bean的生命周期,这里后面再分析。
  • 还有为什么要创建一个基础测试类来进行演示,如果直接使用UserDefinedBeanPostProcessor类进行演示是得不到我们所需要的效果的,因为ApplicationContext对象会自动注册BeanPostProcessor,并且在注册会实例化BeanPostProcessor,然后在第二次调用的时候就会从单例缓存中取值,因此得不到想要的效果。自动注册并实例化BeanPostProcessor参看PostProcessorRegistrationDelegate#registerBeanPostProcessors函数,细读该函数就会豁然开朗。

BeanPostProcessor总结

BeanPostProcessor可以理解为是Spring的一个工厂钩子(其实Spring提供一系列的钩子,如Aware 、InitializingBean、DisposableBean),它是Spring提供的对象实例化阶段强有力的扩展点,允许Spring在实例化bean阶段对其进行定制化修改,比较常见的使用场景是处理标记接口实现类或者为当前对象提供代理实现(例如 AOP)。

BeanPostProcessor的执行时机如下:

108_2.png

注意:一般的BeanFactory是不支持自动注册BeanPostProcessor,需手动调用addBeanPostProcessor进行注册,但是ApplicationContext支持自动注册,但是在其注册过程中就会对BeanPostProcessor进行初始化并进缓存,因此在示例代码中利用了基础测试类来进行演示。

BeanPostProcessor的作用域是容器级别的,它只和所在的容器相关,当BeanPostProcessor完成注册后,它会应用于所有跟它在同一容器内的bean


by Shawn Chen,2019.05.05,上午。

出处:https://www.cnblogs.com/developer_chan/category/1347173.html

文章永久链接:https://tech.souyunku.com/?p=13694


Warning: A non-numeric value encountered in /data/wangzhan/tech.souyunku.com.wp/wp-content/themes/dux/functions-theme.php on line 1154
赞(87) 打赏



未经允许不得转载:搜云库技术团队 » 【spring源码分析】IOC容器初始化——查漏补缺(二)

IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码
IDEA2023.1.3破解,IDEA破解,IDEA 2023.1破解,最新IDEA激活码

评论 抢沙发

大前端WP主题 更专业 更方便

联系我们联系我们

觉得文章有用就打赏一下文章作者

微信扫一扫打赏

微信扫一扫打赏


Fatal error: Uncaught Exception: Cache directory not writable. Comet Cache needs this directory please: `/data/wangzhan/tech.souyunku.com.wp/wp-content/cache/comet-cache/cache/https/tech-souyunku-com/index.q`. Set permissions to `755` or higher; `777` might be needed in some cases. in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php:367 Stack trace: #0 [internal function]: WebSharks\CometCache\Classes\AdvancedCache->outputBufferCallbackHandler() #1 /data/wangzhan/tech.souyunku.com.wp/wp-includes/functions.php(5109): ob_end_flush() #2 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(303): wp_ob_end_flush_all() #3 /data/wangzhan/tech.souyunku.com.wp/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters() #4 /data/wangzhan/tech.souyunku.com.wp/wp-includes/plugin.php(470): WP_Hook->do_action() #5 /data/wangzhan/tech.souyunku.com.wp/wp-includes/load.php(1097): do_action() #6 [internal function]: shutdown_action_hook() #7 {main} thrown in /data/wangzhan/tech.souyunku.com.wp/wp-content/plugins/comet-cache/src/includes/traits/Ac/ObUtils.php on line 367