概述
开发中有时候需要对某个bean
进行整体的加强,但是当前代码中有很多地方使用这个bean
的不同方法;又不想同时修改这些地方留下修改记录
所以我的想法是在spring
初始化bean
过程中用自己的增强bean
进行增强,不侵入业务代码;
整体想法是定义一个装饰器类,对指定bean
的需要增强的方法进行增强;
然后通过BeanPostProcessor.postProcessAfterInitialization
方法,使用增强bean
替换原始bean
;
捞一张bean
的生命周期图;可以看到在postProcessAfterInitialization
方法中进行增强比较合适,因为此时原始bean
已经是可用状态了
demo
流程简单的说就是装饰器模式
增强,然后通过BeanPostProcessor.postProcessAfterInitialization
替换原始bean
package com.xxx.xxx.service.complex;import com.xxx.xxx.dto.WhTailFeeCalBaseInfoDTO;
import com.xxx.xxx.dto.WhTailFeeCalDTO;
import com.xxx.xxx.dto.WhTailFeeCalResultDTO;import java.util.List;public abstract class CalResolveComplexDecorate implements CalResolveComplex {protected CalResolveComplex calResolveComplex;public CalResolveComplexDecorate(CalResolveComplex calResolveComplex) {this.calResolveComplex = calResolveComplex;}@Overridepublic abstract WhTailFeeCalBaseInfoDTO buildFeeBaseInfo(WhTailFeeCalDTO dto);@Overridepublic List<WhTailFeeCalResultDTO> calTailFee(WhTailFeeCalDTO dto) {//默认实现return calResolveComplex.calTailFee(dto);}
}package com.xxx.xxx.service.complex;import com.xxx.xxx.dto.WhTailFeeCalBaseInfoDTO;
import com.xxx.xxx.dto.WhTailFeeCalDTO;
import lombok.extern.slf4j.Slf4j;@Slf4j
public class CalResolveComplexDecorateBuildFeeBaseInfo extends CalResolveComplexDecorate {public CalResolveComplexDecorateBuildFeeBaseInfo(CalResolveComplex calResolveComplex) {super(calResolveComplex);}//增强@Overridepublic WhTailFeeCalBaseInfoDTO buildFeeBaseInfo(WhTailFeeCalDTO dto) {log.info("开始增强buildFeeBaseInfo---------------------");WhTailFeeCalBaseInfoDTO whTailFeeCalBaseInfoDTO = calResolveComplex.buildFeeBaseInfo(dto);log.info("结束增强buildFeeBaseInfo---------------------");return whTailFeeCalBaseInfoDTO;}}package com.xxx.xxx.service.complex;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
@Slf4j
public class CalResolveComplexPostProcess implements BeanPostProcessor, ApplicationListener<ApplicationReadyEvent> {@Resourceprivate ApplicationContext applicationContext;@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if(bean instanceof CalResolveComplex){//此时原始bean已经经过了spring的bean初始化和依赖注入等过程是一个完全可用的beanlog.info("原始bean替换为增强实例");bean = new CalResolveComplexDecorateBuildFeeBaseInfo((CalResolveComplex)bean);}return bean;}@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {log.info("容器启动完成");CalResolveComplex bean = applicationContext.getBean(CalResolveComplex.class);System.out.println(bean);}
}