您的位置:首页 > 汽车 > 时评 > BeanPostProcessor和Ordered

BeanPostProcessor和Ordered

2025/6/19 7:35:23 来源:https://blog.csdn.net/yyuggjggg/article/details/141576734  浏览:    关键词:BeanPostProcessor和Ordered

1. 概述

BeanPostProcessor 和 Ordered 接口用于在Spring容器初始化Bean的过程中进行自定义处理,并控制处理顺序

2. BeanPostProcessor

BeanPostProcessor 接口允许你在Spring容器初始化Bean的前后对Bean进行自定义处理。它有两个方法:

  • postProcessBeforeInitialization(Object bean, String beanName):在Bean初始化之前调用。
  • postProcessAfterInitialization(Object bean, String beanName):在Bean初始化之后调用。
    • bean:容器正在创建的那个bean的引用;
    • beanName:容器正在创建的那个bean的名称;

2.1 bean的生命周期

在这里插入图片描述

描述如下:

  1. 首先由Spring容器创建bean实例;
  2. 为bean的属性注入值;
  3. 若bean实现了各类Aware接口,则调用相应的set方法,
    • 比如说,实现了BeanNameAware接口的bean,此时容器将调用bean的setBeanName方法,将bean的name作为参数;
    • 实现了ApplicationContextAware接口的bean,此时容器将执行bean的setApplicationContext方法,将bean所在的上下文对象作为参数……
  4. 若容器中包含实现了BeanPostProcessor接口的bean,则此时将调用这些bean的postProcessBeforeInitialization方法,将当前正在创建的bean的引用以及bean的name作为参数传入;
  5. 若bean实现了InitializingBean接口,此时将调用bean的afterPropertiesSet方法;
  6. 若bean指定了自定义的初始化方法,比如说通过配置文件的init-method选项,则此时将执行这个自定义初始化方法;
  7. 若容器中包含实现了BeanPostProcessor接口的bean,则此时将调用这些bean的postProcessAfterInitialization方法,将当前正在创建的bean的引用以及bean的name作为参数传入;
    • 可以在一个容器中注册多个不同的BeanPostProcessor的实现类对象,而bean在创建的过程中,将会轮流执行这些对象实现的before和after方法
    • 执行顺序通过BeanPostProcessor的实现类实现这个Ordered接口,并实现接口的getOrder方法
  8. 这个时候,bean就算是初始化完毕,可以被使用了,在容器销毁之前,这个对象将一直保存在容器中;
  9. bean实现了DisposableBean接口,则在容器销毁时,会调用bean的destroy方法;
  10. 如果bean定义了自定义的销毁方法,则在容器销毁时,会调用这个自定义的销毁方法;
  11. 容器销毁成功,bean也被回收

2.2 使用注意

2.2.1 BeanPostProcessor依赖的bean,不会执行BeanPostProcessor的方法

当我们在BeanPostProcessor的实现类中,依赖了其他的bean,
那么被依赖的bean被创建时,将不会执行它所在的BeanPostProcessor实现类实现的方法

比如我们修改PostBean的实现,如下所示:

  • 容器在创建User这个bean时,不会执行PostBean实现的两个方法,
  • 因为由于PostBean依赖于user,所以user需要在PostBean之前创建完成,
  • 这也就意味着在user创建时,PostBean还未初始化完成,所以不会调用它的方法
@Component
public class PostBean implements BeanPostProcessor, Ordered {// 让PostBean依赖User@Autowiredprivate User user;@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}

2.2.2 BeanPostProcessor以及依赖的bean无法使用AOP

Spring的AOP代理就是作为BeanPostProcessor实现的

所以我们无法对BeanPostProcessor的实现类使用AOP织入通知,

也无法对BeanPostProcessor的实现类依赖的bean使用AOP织入通知。

2.3 将BeanPostProcessor注册到Spring容器中

2.3.1 @Component注解

使用@Component注解:在实现类上添加@Component注解,这样Spring会自动扫描并注册这个bean。

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {// 实现方法
}

2.3.2 使用@Bean配置BeanPostProcessor的限制

使用Java配置类:如果你使用的是Java配置类,可以在配置类中注册这个bean。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyBeanPostProcessor myBeanPostProcessor() {return new MyBeanPostProcessor();}
}

示例如下:


/*** 此BeanPostProcessor的实现类,还实现了Ordered接口*/
public class PostBean implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {System.out.println("before -- " + beanName);return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {System.out.println("after -- " + beanName);return bean;}@Overridepublic int getOrder() {return 0;}
}

在配置类中,声明PostBean可以有以下几种方式

  1. 只有第一种和第二种方式,会让Spring容器将PostBean当作BeanPostProcessor处理
  2. 而第三种方式,则会被当作一个普通Bean处理,实现BeanPostProcessor的两个方法都不会被调用,
    • 因为在PostBean的继承体系中,Ordered和BeanPostProcessor是同级别的,
    • Spring无法识别出这个Ordered对象,也是一个BeanPostProcessor对象;
    • 但是使用PostBean却可以,因为PostBean类型就是BeanPostProcessor的子类型
    • 所以,在使用@Bean声明工厂方法返回BeanPostProcessor实现类对象时,返回值必须是BeanPostProcessor类型,或者更低级的类型
    @Configuration
    public class BeanConfig {// 方式1:PostBean@Beanpublic PostBean postBean() {return new PostBean();}// 方式2:返回值为BeanPostProcessor@Beanpublic BeanPostProcessor postBean() {return new PostBean();}// 方式3:返回值为Ordered@Beanpublic Ordered postBean() {return new PostBean();}
    }
    

2.3.3 spring.factories

创建 BeanPostProcessor 实现类:

首先,创建一个实现 BeanPostProcessor 接口的类。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyAutoConfiguration {@Beanpublic MyBeanPostProcessor myBeanPostProcessor() {return new MyBeanPostProcessor();}
}

创建自动配置类:创建一个自动配置类,并在其中定义 BeanPostProcessor 的 @Bean 方法

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MyAutoConfiguration {@Beanpublic MyBeanPostProcessor myBeanPostProcessor() {return new MyBeanPostProcessor();}
}

创建 spring.factories 文件:在 src/main/resources/META-INF/ 目录下创建 spring.factories 文件,并在其中添加自动配置类的全限定名

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration

目录结构

src/main/java/com/example/MyBeanPostProcessor.javaMyAutoConfiguration.java
src/main/resources/META-INF/spring.factories

2.3.4 Xml

在XML中注册这个bean。

<bean id="myBeanPostProcessor" class="com.example.MyBeanPostProcessor"/>

3. Order

Ordered 接口用于控制多个 BeanPostProcessor 的执行顺序。它有一个方法:

  • getOrder():返回一个整数值,表示处理器的顺序。值越小,优先级越高。

4. 多个 BeanPostProcessor 的顺序

如果有多个 BeanPostProcessor,可以通过实现 Ordered 接口来控制它们的执行顺序。值越小,优先级越高。

5. 举例

自定义Bean后处理器

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;@Component
public class CustomBeanPostProcessor implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof MyService) {System.out.println("Before Initialization: " + beanName);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof MyService) {System.out.println("After Initialization: " + beanName);}return bean;}@Overridepublic int getOrder() {return 1; // 优先级,值越小优先级越高}
}

服务类

import org.springframework.stereotype.Service;@Service
public class MyService {public void serve() {System.out.println("Service method executed");}
}

主类

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

另一个自定义Bean后处理器

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;@Component
public class AnotherBeanPostProcessor implements BeanPostProcessor, Ordered {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof MyService) {System.out.println("Another Before Initialization: " + beanName);}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof MyService) {System.out.println("Another After Initialization: " + beanName);}return bean;}@Overridepublic int getOrder() {return 2; // 优先级,值越小优先级越高}
}

运行示例

Before Initialization: myService
Another Before Initialization: myService
After Initialization: myService
Another After Initialization: myService
Service method executed

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com