分类操作,可以通过引入对 Bean 的前置和后置处理
BeanPostProcessor 的接口定义,实现这两个方法的任意一个,就能拿到实例化的 bean,该方法返回结果也是一个 bean,因此可以对传入的 bean 进行自定义修改后返回
java
public interface BeanPostProcessor {
// 在 bean 的初始化回调前进行调用, 该方法拿到的 bean 是已经经过了属性填充的 bean
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 在 bean 的初始化回调后进行调用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}深入理解 BeanPostProcessor
BeanPostProcessor 的执行时机
需要搞清楚 before 和 after 的执行阶段 
BeanPostProcessor 的应用场景
- 解析 Bean 的自定义注解,针对注解做一些前置处理
- 归类 Bean,聚合处理过程
案例
编写枚举
java
/**
* 优惠券类型
*
* @author 朔风
* @date 2026-01-14 14:57
*/
public enum CouponTypeEnum {
MAN_JIAN("man_jian", "满减券"),
MAN_FAN("man_fan", "满返券"),
ZHE_KOU("zhe_kou", "折扣券"),
;
CouponTypeEnum(String type, String description) {
this.type = type;
this.description = description;
}
private final String type;
private final String description;
public String getType() {
return type;
}
public String getDescription() {
return description;
}
}自定义注解
java
/**
* 自定义注解
*
* @author 朔风
* @date 2026-01-14 15:00
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CouponHandlerProcessor {
/** 优惠券类型 */
CouponTypeEnum value();
}统一接口
java
/**
* coupon 处理器服务接口定义
*
* @author 朔风
* @date 2026-01-14 15:01
*/
public interface ICouponHandlerService {
void process(String coupon);
}接口的各种实现
满返券
java
@Service
@CouponHandlerProcessor(CouponTypeEnum.MAN_FAN)
public class ManFanCouponHandlerServiceImpl implements ICouponHandlerService {
private static final Logger logger = LoggerFactory.getLogger(ManFanCouponHandlerServiceImpl.class);
@Override
public void process(String coupon) {
logger.info("ManFan process {}", coupon);
}
}满减券
java
@Service
@CouponHandlerProcessor(CouponTypeEnum.MAN_JIAN)
public class ManJianCouponHandlerServiceImpl implements ICouponHandlerService {
private static final Logger logger = LoggerFactory.getLogger(ManJianCouponHandlerServiceImpl.class);
@Override
public void process(String coupon) {
logger.info("ManJian process {}", coupon);
}
}折扣券
java
@Service
@CouponHandlerProcessor(CouponTypeEnum.ZHE_KOU)
public class ZheKouCouponHandlerServiceImpl implements ICouponHandlerService {
private static final Logger logger = LoggerFactory.getLogger(ZheKouCouponHandlerServiceImpl.class);
@Override
public void process(String coupon) {
logger.info("ZheKou process {}", coupon);
}
}处理器工厂
java
/**
* coupon 处理器工厂类
*
* @author 朔风
* @date 2026-01-14 15:01
*/
@Component
public class CouponHandlerFactory implements BeanPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(CouponHandlerFactory.class);
private static final Map<CouponTypeEnum, ICouponHandlerService> serviceMap =
new ConcurrentHashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof ICouponHandlerService) {
// 获取对象运行时对象类
Class<?> clazz = bean.getClass();
// 获取自定义的注解
CouponHandlerProcessor annotation = clazz.getAnnotation(CouponHandlerProcessor.class);
// TODO 是不是可以对 bean 进行校验
// 绑定对应关系
serviceMap.put(annotation.value(), (ICouponHandlerService) bean);
logger.info("CouponHandlerFactory {} ....", annotation.value());
}
return bean;
}
/***
* 根据优惠券类型获取优惠券处理器
*
* @author 朔风
* @date 2026/1/14 15:09
* @param type type
* @return com.github.itdachen.post.ICouponHandlerService
*/
public ICouponHandlerService handler(CouponTypeEnum type) {
return serviceMap.get(type);
}
}测试
java
@SpringBootTest
public class CouponHandlerFactoryTests {
@Autowired
private CouponHandlerFactory couponHandlerFactory;
@Test
void test() {
couponHandlerFactory.handler(CouponTypeEnum.MAN_FAN).process("====");
}
}
剑鸣秋朔