1. Spring Bean 的生命周期流程图
Spring Bean 的完整生命周期从创建 Spring 容器开始,直到最终 Spring 容器销毁 Bean,这其中包含了一系列回调方法。具体如下
各种接口方法分类
Bean 的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:
- Bean 自身的方法: 这个包括了 Bean 本身调用的方法和通过
@PostConstruct
和@PreDestroy
指定的方法 - Bean 级生命周期接口方法: 这个包括了 BeanNameAware、BeanFactoryAware、InitializingBean 和 DiposableBean 这些接口的方法
- 容器级生命周期接口方法: 这个包括了 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
- 工厂后处理器接口方法: 这个包括了 AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer 等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
2. 验证
2.1.实现 BeanFactoryPostProcessor 接口
Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义BeanFactoryPostProcessor,通过设置order
属性来确定各个BeanFactoryPostProcessor执行顺序。
@Component
public class TestBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(TestBeanFactoryPostProcessor.class);
public TestBeanFactoryPostProcessor() {
super();
logger.info("这是 BeanFactoryPostProcessor 实现类构造器!!");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0) throws BeansException {
logger.info("BeanFactoryPostProcessor 调用 postProcessBeanFactory 方法");
BeanDefinition bd = arg0.getBeanDefinition("imageBase64Utils");
bd.getPropertyValues().addPropertyValue("phone", "110");
}
}
@Setter
@Getter
@Component
public class ImageBase64Utils {
private String phone;
}
2.2.Bean 自身的方法
TestBeanMethod 自身实现了 BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean 这四个接口,并通过 @PostConstruct 和 @PreDestroy 指定了初始化后以及销毁前的方法
@Component
public class TestBeanMethod implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(TestBeanMethod.class);
private BeanFactory beanFactory;
private String beanName;
private String phone;
public String getBeanName() {
return beanName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
logger.info("【注入属性】注入属性 phone");
this.phone = phone;
}
public TestBeanMethod() {
logger.info("【构造器】调用构造方法初始化 bean");
}
// 获取 BeanFactory 对象
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
logger.info("【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()");
}
@PostConstruct
public void init() {
logger.info("【@PostConstruct】自定义 init 方法");
}
@PreDestroy
public void des() {
logger.info("【@PreDestroy】自定义 destroy 方法");
}
@Override
public void setBeanName(String s) {
this.beanName = s;
logger.info("【注入属性】注入属性name");
}
@Override
public void destroy() throws Exception {
logger.info("【DisposableBean接口】调用DisposableBean.destroy()");
}
@Override
public void afterPropertiesSet() throws Exception {
logger.info("【InitializingBean接口】调用InitializingBean.afterPropertiesSet()");
}
}
2.3.实现 InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor 接口本质是 BeanPostProcessor 的子接口,一般继承 Spring 为其提供的适配器类 InstantiationAwareBeanPostProcessorAdapter 来使用它
@Component
public class TestInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
private static final Logger logger = LoggerFactory.getLogger(TestInstantiationAwareBeanPostProcessor.class);
public TestInstantiationAwareBeanPostProcessor() {
super();
logger.info("这是 InstantiationAwareBeanPostProcessorAdapter 实现类构造器!!");
}
// 接口方法、实例化Bean之前调用
@Override
public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
logger.info(String.format("InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation方法,beanName=%s", beanName));
return null;
}
// 接口方法、实例化Bean之后调用
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info(String.format("InstantiationAwareBeanPostProcessor 调用 postProcessAfterInitialization方法,beanName=%s", beanName));
return bean;
}
}
2.4.实现 BeanPostProcessor 接口
BeanPostProcessor 接口包括 2个方法 postProcessAfterInitialization 和 postProcessBeforeInitialization,这两个方法的第一个参数都是要处理的 Bean 对象,第二个参数都是 Bean 的 name。返回值也都是要处理的Bean对象。
/**
* 在 Bean 的初始化前后执行
*/
@Component
public class TestBeanPostProcessor implements BeanPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(TestBeanPostProcessor.class);
public TestBeanPostProcessor() {
super();
logger.info("这是 BeanPostProcessor 实现类构造器!!");
}
@Override
public Object postProcessAfterInitialization(Object arg0, String arg1) throws BeansException {
logger.info("BeanPostProcessor 接口方法 postProcessAfterInitialization 对属性进行更改!");
return arg0;
}
@Override
public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException {
logger.info("BeanPostProcessor 接口方法 postProcessBeforeInitialization 对属性进行更改!");
return arg0;
}
}
2.5.测试
public class ApplicationContextRun {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext("cn.cychee.imageservice.logic");
TestBeanMethod testBeanMethod = applicationContext.getBean(TestBeanMethod.class);
((AnnotationConfigApplicationContext) applicationContext).registerShutdownHook();
}
}
2.6.测试结果
c.c.i.l.TestBeanFactoryPostProcessor [19] 这是 BeanFactoryPostProcessor 实现类构造器!!
c.c.i.l.TestBeanFactoryPostProcessor [24] BeanFactoryPostProcessor 调用 postProcessBeanFactory 方法
c.c.i.logic.TestBeanPostProcessor [19] 这是 BeanPostProcessor 实现类构造器!!
.TestInstantiationAwareBeanPostProcessor[16] 这是 InstantiationAwareBeanPostProcessorAdapter 实现类构造器!!
.TestInstantiationAwareBeanPostProcessor[22] InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation方法,beanName=imageBase64Utils
c.c.i.logic.TestBeanPostProcessor [30] BeanPostProcessor 接口方法 postProcessBeforeInitialization 对属性进行更改!
c.c.i.logic.TestBeanPostProcessor [24] BeanPostProcessor 接口方法 postProcessAfterInitialization 对属性进行更改!
.TestInstantiationAwareBeanPostProcessor[29] InstantiationAwareBeanPostProcessor 调用 postProcessAfterInitialization方法,beanName=imageBase64Utils
.TestInstantiationAwareBeanPostProcessor[22] InstantiationAwareBeanPostProcessor 调用 postProcessBeforeInstantiation方法,beanName=testBeanMethod
c.c.imageservice.logic.TestBeanMethod [35] 【构造器】调用构造方法初始化 bean
c.c.imageservice.logic.TestBeanMethod [58] 【注入属性】注入属性name
c.c.imageservice.logic.TestBeanMethod [42] 【BeanFactoryAware接口】调用BeanFactoryAware.setBeanFactory()
c.c.i.logic.TestBeanPostProcessor [30] BeanPostProcessor 接口方法 postProcessBeforeInitialization 对属性进行更改!
c.c.imageservice.logic.TestBeanMethod [47] 【@PostConstruct】自定义 init 方法
c.c.imageservice.logic.TestBeanMethod [68] 【InitializingBean接口】调用InitializingBean.afterPropertiesSet()
c.c.i.logic.TestBeanPostProcessor [24] BeanPostProcessor 接口方法 postProcessAfterInitialization 对属性进行更改!
.TestInstantiationAwareBeanPostProcessor[29] InstantiationAwareBeanPostProcessor 调用 postProcessAfterInitialization方法,beanName=testBeanMethod
c.c.imageservice.logic.TestBeanMethod [52] 【@PreDestroy】自定义 destroy 方法
c.c.imageservice.logic.TestBeanMethod [63] 【DisposableBean接口】调用DisposableBean.destroy()
3.使用场景
这里结合策略设计模式 和 BeanFactoryPostProcessor 的实现类,来处理一个根据 不同的订单类型 使用 不同的处理器功能。
- 订单类型的处理 通过 订单类型注解(OrderHandlerType)和实现 AbstractOrderHandler 接口就可以扩展,实现了“高内聚和低耦合”。
- 取消了 if…else if…,代码容易阅读和理解。
3.1.订单处理注解
订单处理注解,用于标注订单的处理类型
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface OrderHandlerType {
// 订单处理类型
OrderTypeEnum value() default OrderTypeEnum.offline;
}
3.2.实现 BeanFactoryPostProcessor 接口
实现 BeanFactoryPostProcessor 接口,用于在 Spring 容器启动成功后从容器中获取 AbstractOrderHandler 接口的实现类,并将实现类存入到 订单处理容器中
/**
* 1. 实现 BeanFactoryPostProcessor 接口,用于在 Spring 容器启动成功后从容器中获取 AbstractOrderHandler 接口的实现类 <br>
* 2. 并将实现类存入到 订单处理容器中
*
*/
@Component
public class OrderBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
public OrderBeanFactoryPostProcessor() {
super();
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 1. 获取 AbstractOrderHandler 接口的实现类
Map<String, AbstractOrderHandler> orderHandlerMap = beanFactory.getBeansOfType(AbstractOrderHandler.class);
// 2. 订单类别 对应的 具体实现类
Map<OrderTypeEnum, Class<?>> map = new HashMap<>();
orderHandlerMap.forEach((k,v) -> {
OrderHandlerType orderHandlerType = v.getClass().getDeclaredAnnotation(OrderHandlerType.class);
OrderTypeEnum orderTypeEnum = orderHandlerType.value();
map.put(orderTypeEnum, v.getClass());
});
// 将 订单类别 对应的 具体实现类 的 map 存储到 applicationContext 中
beanFactory.registerSingleton(OrderHandlerType.class.getName(), map);
}
}
3.3.订单的实体和订单类型枚举
- OrderEntity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class OrderEntity {
private Long id;
private Long userId;
private OrderTypeEnum orderType;
private Date orderDate;
private BigDecimal orderAmount;
}
- OrderTypeEnum
/**
* 订单类型枚举
*/
public enum OrderTypeEnum {
online, offline;
}
3.4.订单处理接口
public interface AbstractOrderHandler {
void handle(OrderEntity orderEntity);
}
3.5.订单处理容器
/**
* 订单处理容器,根据订单类型返回对应的 订单处理器
*/
@Component
public class OrderHandlerContext {
@Autowired
private ApplicationContext applicationContext;
public AbstractOrderHandler getOrderHandler(OrderTypeEnum orderTypeEnum) {
Map<OrderTypeEnum, Class<?>> map = applicationContext.getBean(OrderHandlerType.class.getName(), Map.class);
Class<?> clazz = map.get(orderTypeEnum);
return (AbstractOrderHandler) applicationContext.getBean(clazz);
}
}
3.6.具体的订单处理器
- 处理线下订单, 带有
@OrderHandlerType(OrderTypeEnum.offline)
注解
@Component
@OrderHandlerType(OrderTypeEnum.offline)
public class ProcessOfflineOrderHandler implements AbstractOrderHandler {
private static final Logger logger = LoggerFactory.getLogger(ProcessOfflineOrderHandler.class);
@Override
public void handle(OrderEntity orderEntity) {
logger.info("order handler,type={}", orderEntity.getOrderType());
}
}
- 处理线上订单,带有
@OrderHandlerType(OrderTypeEnum.online)
注解
@Component
@OrderHandlerType(OrderTypeEnum.online)
public class ProcessOnlineOrderHandler implements AbstractOrderHandler {
private static final Logger logger = LoggerFactory.getLogger(ProcessOnlineOrderHandler.class);
@Override
public void handle(OrderEntity orderEntity) {
logger.info("handle order,type {}", orderEntity.getOrderType());
}
}
3.7.测试
public class ApplicationContextOrderRun {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.ckjava.test");
// 1. 获取订单处理上下文
OrderHandlerContext orderHandlerContext = applicationContext.getBean(OrderHandlerContext.class);
// 2. 传入的订单实体
OrderEntity orderEntity = new OrderEntity();
orderEntity.setOrderType(OrderTypeEnum.offline);
// 3. 根据订单类型获取对应的订单处理器
AbstractOrderHandler abstractOrderHandler = orderHandlerContext.getOrderHandler(orderEntity.getOrderType());
// 4. 最后处理订单
abstractOrderHandler.handle(orderEntity);
}
}
原文