Skip to content
章节导航

分类操作,可以通过引入对 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("====");
    }

}