spring 扩展点之后置处理器(PostProcessor)及Aware接口

PostProcessor

后置处理器(PostProcessor)是一种扩展机制,它可以让我们在Bean实例化、初始化和销毁的过程中加入自己的逻辑处理

BeanFactoryPostProcessor

BeanFactory后置处理器,用于在Bean工厂实例化Bean之前对Bean定义进行修改或自定义处理。它允许我们在Spring容器加载Bean定义后,在实例化Bean之前对这些定义进行干预和修改。

要想使用BeanFactory后置处理器,只需要实现BeanFactoryPostProcessor接口实现其postProcessBeanFactory方法。在postProcessBeanFactory接口可以获取到beanFacotry可以对bean定义进行操作。

用例:

@Component
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition def = beanFactory.getBeanDefinition("xxx");
        def.setLazyInit(true);
    }
}

容器自动加载的BeanFactory后置处理器:

以AnnotationConfigApplicationContext容器实例化过程看,在AnnotationConfigApplicationContext构造函数会创建一个AnnotatedBeanDefinitionReader实例,然后会通过工具类判断注册一些processorAnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      BeanDefinitionRegistry registry, @Nullable Object source) {

   DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
   if (beanFactory != null) {
      if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
         beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      }
      if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
         beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      }
   }

   Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

   if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
   if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
   if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition();
      try {
         def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
               AnnotationConfigUtils.class.getClassLoader()));
      }
      catch (ClassNotFoundException ex) {
         throw new IllegalStateException(
               "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
      }
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
   }

   if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
      RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      def.setSource(source);
      beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
   }

   return beanDefs;
}

BeanDefinitionRegistryPostProcessor:

Bean定义注册后置处理器,这个也是在bean被初始化之前对bean定义进行修改,比BeanFactory后置处理其稍早一些,暴露的是BeanDefinitionRegistry注册对象。同时Bean定义注册后置处理器是继承了BeanFacotry后置处理器,也可以获取BeanFacotry。

用例:实现BeanDefinitionRegistryPostProcessor接口即可

@Component
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
       //新加载一个bean
        BeanDefinition selfDef = BeanDefinitionBuilder.genericBeanDefinition(SelfDefBean.class).getBeanDefinition();
        registry.registerBeanDefinition("selfDef",selfDef);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		//TODO 
    }
}

上面BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor两种类型的后置处理器都是容器在bean加载之前暴露BeanDefinitionRegistry或beanFactory允许开发人员对beandef进行修改的机会。因为再往后就要开始对bean进行实例化了。那么这两种后置处理器在什么时候执行的呢?

在context的refresh方法里有几步是关于BeanFactoryPostProcessor的操作

public void refresh() throws BeansException, IllegalStateException {
      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);
      try {
         //这里是个空方法
         postProcessBeanFactory(beanFactory);
         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);
        //...
      }
}

prepareBeanFactory方法,这里会初始化一些系统默认的post

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

然后在invokeBeanFactoryPostProcessors方法调用post。最后在PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法获取不同类型的post并执行。

public static void invokeBeanFactoryPostProcessors(
      ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

   //省略很多,优先级较高的容器级post...
   //获取BeanFactoryPostProcessor类型的post
   String[] postProcessorNames =
         beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

   // ...

   // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
   //执行post
   invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

   // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
   //...
}

获取post方法beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)。从beanDef里获取BeanFactoryPostProcessor类型的。所以我们要自定义一个postProcessor只要定义一个实现BeanFactoryPostProcessor接口的bean就好了。

调用就很简单了,调用post实现的接口方法postProcessBeanFactory就可以了。

private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanFactory(beanFactory);
      postProcessBeanFactory.end();
   }
}
BeanPostProcessor

bean初始化前后通知,这个是在每个bean初始化时候都会执行

同样post的解析获取在refresh方法有一步registerBeanPostProcessors(beanFactory);同factory的post查找方法也是通过beanFactory.getBeanNamesForType(BeanPostProcessor.class)获取BeanPostProcessor。所以要自定义一个beanpost只要实现BeanPostProcessor接口,重写 postProcessBeforeInitialization,postProcessAfterInitialization两个方法。在bean的实例化前后执行

执行时机

从bean的创建开始,

在AbstractAutowireCapableBeanFactory.doCreateBean方法会有

//注入依赖属性
populateBean(beanName, mbd, instanceWrapper);
//初始化bean,调用post方法
exposedObject = initializeBean(beanName, exposedObject, mbd);

在initializeBean方法的最后会调用post方法

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }
   Object wrappedBean = bean;
   //isSynthetic 判断是否是容器自身定义的
   if (mbd == null || !mbd.isSynthetic()) {//调用BeanPostProcessorsBefore
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   //调用初始化方法
   invokeInitMethods(beanName, wrappedBean, mbd);
   
   if (mbd == null || !mbd.isSynthetic()) {//调用after
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

调用也是调用post实现的接口方法。

Aware

Spring Aware 是一个接口,它定义了一组回调方法,用于在 Spring 容器初始化过程中将特定的对象注入到 Spring 管理的 Bean 中。通过实现 Spring Aware 接口并重写对应的回调方法,可以在 Bean 初始化的过程中获取 Spring 容器中的一些资源或上下文信息。

Spring Aware 的作用是使 Bean 能够感知 Spring 容器的存在和特性,从而增强 Bean 的功能和灵活性。

Aware只是一个空接口,ApplicationContextAware 、BeanFactoryAware 、EnvironmentAware 、EnvironmentAware 、BeanNameAware 等Aware接口都继承自该接口。实现不同的功能。每个接口有不同的接口方法。应用开发程序只需要实现不同的接口方法即可。

具体来说,Spring Aware 主要有以下几个作用:

  1. 获取 Spring 容器上下文(ApplicationContext):通过实现 ApplicationContextAware 接口,可以在 Bean 实例化后,将 Spring 容器的上下文对象注入到 Bean 中,从而获取 Spring 容器的功能和资源,如获取其他 Bean、访问配置文件等。这样的功能在某些场景下非常实用,例如需要动态获取其他 Bean 或需要读取外部配置文件等。
  2. 获取 BeanFactory 对象:通过实现 BeanFactoryAware 接口,可以在 Bean 实例化后,将 Spring 容器的 BeanFactory 对象注入到 Bean 中。BeanFactory 是 Spring 容器的核心接口,提供了创建和管理 Bean 的能力,借助 BeanFactoryAware,可以直接操作 BeanFactory,执行更高级的任务,如动态注册 Bean 等。
  3. 获取 Environment 对象:通过实现 EnvironmentAware 接口,可以将 Spring 容器的 Environment 对象注入到 Bean 中。Environment 提供了访问应用程序运行环境(如配置文件、系统属性等)的方法,通过 EnvironmentAware,可以方便地获取和操作这些环境信息。
  4. 其他 Aware 接口:除了上述几个常用的 Aware 接口外,Spring 还提供了一些其他的 Aware 接口,如 BeanClassLoaderAware、BeanNameAware 等,它们分别提供了获取类加载器和 Bean 名称等功能。这些 Aware 接口可以根据具体需求来使用,增强 Bean 的功能和扩展性。

总的来说,Spring Aware 的作用是为 Bean 提供访问和利用 Spring 容器资源的能力,通过回调方法将特定的对象或上下文注入到 Bean 中,使得 Bean 能够与 Spring 容器进行交互,获取更多的功能和信息,从而更好地适应各种开发需求。

例:通过ApplicationContextAware获取ApplicationContext

public class MyApplicationAware implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

通过EnvironmentAware获取Environment

@Component
public class MyEnvironmentAware implements EnvironmentAware{
    @Override
    public void setEnvironment(Environment environment) {
        System.out.println(Arrays.toString(environment.getActiveProfiles()));
    }
}

aware执行时机

从doCreateBean创建bean方法开始:

populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);

initializeBean方法会调用

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   //step1 - 调用aware方法
   invokeAwareMethods(beanName, bean);

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //step2 - beanPostProcessorBefore
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }
   //step3 - 调用初始化方法
   invokeInitMethods(beanName, wrappedBean, mbd);

   if (mbd == null || !mbd.isSynthetic()) {
      //step4-调用beanPostProcessorAfter
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

step1 - 调用aware方法

invokeAwareMethods方法:

private void invokeAwareMethods(String beanName, Object bean) {
   if (bean instanceof Aware) { 
      if (bean instanceof BeanNameAware) { //实现了BeanNameAware
         ((BeanNameAware) bean).setBeanName(beanName);
      }
      if (bean instanceof BeanClassLoaderAware) {//实现了BeanClassLoaderAware
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {//实现了BeanFactoryAware
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

step2 - beanPostProcessorBefore调用

另一部分调用通过ApplicationContextAwareProcessor的beforepost方法调用

会调用每个processor的postProcessBeforeInitialization(result, beanName),ApplicationContextAwareProcessor方法内会调用invokeAwareInterfaces(bean)方法

invokeAwareInterfaces方法代码:

private void invokeAwareInterfaces(Object bean) {
   if (bean instanceof EnvironmentAware) {
      ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
   }
   if (bean instanceof EmbeddedValueResolverAware) {
      ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
   }
   if (bean instanceof ResourceLoaderAware) {
      ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
   }
   if (bean instanceof ApplicationEventPublisherAware) {
      ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
   }
   if (bean instanceof MessageSourceAware) {
      ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
   }
   if (bean instanceof ApplicationStartupAware) {
      ((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());
   }
   if (bean instanceof ApplicationContextAware) {
      ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
   }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值