Spring Bean BeanPostProcessor 后处理器



  • Bean 后处理器

    BeanPostProcessor接口定义了回调方法,您可以实现这些回调方法来提供自己的实例化逻辑、依赖解析逻辑等。您还可以通过插入一个或多个BeanPostProcessor实现,在Spring容器完成实例化、配置和初始化bean之后实现一些定制逻辑。
    您可以配置多个BeanPostProcessor接口,并且可以通过设置order属性来控制这些BeanPostProcessor接口的执行顺序,该属性提供了BeanPostProcessor实现的有序接口。
    BeanPostProcessor操作bean(或对象)实例,这意味着Spring IoC容器实例化一个bean实例,然后BeanPostProcessor接口完成它们的工作。
    ApplicationContext自动检测用BeanPostProcessor接口的实现定义的任何bean,并将这些bean注册为后处理器,然后容器在创建bean时适当地调用这些bean。
  • 实例

    下面的示例演示如何在ApplicationContext的上下文中编写,注册和使用BeanPostProcessor
    假设我们拥有一个运行良好的Eclipse IDE,并采取以下步骤来创建一个Spring应用程序:
    1. 创建一个名称为SpringExample的项目,并在创建的项目的src文件夹下创建一个包com.jc2182
    2. 使用“添加外部JAR”选项添加所需的Spring库,如“Spring Hello World示例”一章中所述。
    3. 在com.jc2182包下创建Java类HelloWorld,InitHelloWorld和MainApp。
    4. 在src文件夹下创建Beans配置文件Beans.xml。
    5. 最后一步是创建所有Java文件和Bean配置文件的内容,然后按以下说明运行应用程序。
    这是HelloWorld.java文件的内容:
    package com.jc2182;
    
    public class HelloWorld {
       private String message;
    
       public void setMessage(String message){
          this.message  = message;
       }
       public void getMessage(){
          System.out.println("Your Message : " + message);
       }
       public void init(){
          System.out.println("Bean is going through init.");
       }
       public void destroy(){
          System.out.println("Bean will destroy now.");
       }
    }
    
    这是实现BeanPostProcessor的一个非常基本的示例,该示例在初始化任何bean之前和之后都显示bean名称。您可以在初始化bean之前和之后实现更复杂的逻辑,因为您可以在两个后处理器方法中访问bean对象
    这是InitHelloWorld.java文件的内容
    package com.jc2182;
    
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.beans.BeansException;
    
    public class InitHelloWorld implements BeanPostProcessor {
       public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
          
          System.out.println("BeforeInitialization : " + beanName);
          return bean;  // 您也可以返回任何其他对象
       }
       public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
          
          System.out.println("AfterInitialization : " + beanName);
          return bean;  // 您也可以返回任何其他对象
       }
    }
    
    以下是MainApp.java文件的内容。在这里,您需要注册一个在AbstractApplicationContext类上声明的关闭钩子registerShutdownHook()方法。这将确保正常关闭并调用相关的destroy方法。
    package com.jc2182;
    
    import org.springframework.context.support.AbstractApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MainApp {
       public static void main(String[] args) {
          AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
    
          HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
          obj.getMessage();
          context.registerShutdownHook();  // 注册关闭钩子方法 ,确保正常关闭得以调用相关的销毁方法
       }
    }
    
    以下是所需的配置文件Beans.xml
    <?xml version = "1.0" encoding = "UTF-8"?>
    
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
       <bean id = "helloWorld" class = "com.jc2182.HelloWorld"
          init-method = "init" destroy-method = "destroy">
          <property name = "message" value = "Hello World!"/>
       </bean>
    
       <bean class = "com.jc2182.InitHelloWorld" />
    
    </beans>
    
    完成创建源和Bean配置文件后,让我们运行该应用程序。如果您的应用程序一切正常,它将显示以下消息:
    BeforeInitialization : helloWorld
    Bean is going through init.
    AfterInitialization : helloWorld
    Your Message : Hello World!
    Bean will destroy now.