概述
开发中有时候需要对某个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;
}
@Override
public abstract WhTailFeeCalBaseInfoDTO buildFeeBaseInfo(WhTailFeeCalDTO dto);
@Override
public 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);
}
//增强
@Override
public 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> {
@Resource
private ApplicationContext applicationContext;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(bean instanceof CalResolveComplex){
//此时原始bean已经经过了spring的bean初始化和依赖注入等过程是一个完全可用的bean
log.info("原始bean替换为增强实例");
bean = new CalResolveComplexDecorateBuildFeeBaseInfo((CalResolveComplex)bean);
}
return bean;
}
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
log.info("容器启动完成");
CalResolveComplex bean = applicationContext.getBean(CalResolveComplex.class);
System.out.println(bean);
}
}