前言
有人说不要用业务类实现InitializingBean接口,可以借助自定义的注解来实现类似的逻辑。那我们换这种思路实现下。
定义注解PayType/** * 消息通知类型注解 * @author francis * */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface PayType { /** * 支付类型 * @return */ PayTypeEnum value(); }
其中PayTypeEnum枚举
@Getter @AllArgsConstructor public enum PayTypeEnum { WX("WX", "微信"), ZFB("A","支付宝支付"),; private String type; private String desc; }BeanPostProcessor(Bean后置处理器)
功能:它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。
postProcessBeforeInitialization方法会在每一个bean对象的初始化方法调用之前回调
postProcessAfterInitialization方法会在每个bean对象的初始化方法调用之后被回调
源码如下:
package org .springframework .beans .factory .config ; import org .springframework .beans .BeansException ; import org .springframework .lang .Nullable ; public interface BeanPostProcessor { @Nullable default Object postProcessBeforeInitialization ( Object bean , String beanName ) throws BeansException { return bean ; } @Nullable default Object postProcessAfterInitialization ( Object bean , String beanName ) throws BeansException { return bean ; } }
两个方法入参说明:
bean:容器正在创建的那个bean的引用beanName:容器正在创建的那个bean的名称
策略工厂实现BeanPostProcessor接口getClass() 返回此 Object 的运行时该对象的类. 该方法返回一个Class对象, 可以通过该对象可以获取某个类的相关信息, 如构造方法 属性 方法 等
import com .example .demo .celuemoshi .PayService ; import com .example .demo .celuemoshi .PayTypeEnum ; import lombok .extern .slf4j .Slf4j ; import org .springframework .beans .BeansException ; import org .springframework .beans .factory .config .BeanPostProcessor ; import org .springframework .lang .Nullable ; import org .springframework .stereotype .Component ; import java .util .Map ; import java .util .concurrent .ConcurrentHashMap ; @Component @Slf4j public class StrategyFactory2 implements BeanPostProcessor { private static final Map < PayTypeEnum , PayService > serviceMap = new ConcurrentHashMap <> ( ) ; /** * @param bean 实例化bean的引用 * @param beanName 实例化bean的名字 * @return * @throws @Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { // 只对实现了PayService的类做操作 if (bean instanceof PayService) { //获取对象运行时该对象的类 Class clazz = bean.getClass(); //获取自定义的注解 PayType annotation = clazz.getAnnotation(PayType.class); //绑定对应关系 serviceMap.put(annotation.value(), (PayService) bean); } return bean; } /* * * 寻找对应得策略处理器 */ public PayService getHandler(PayTypeEnum type){ return serviceMap.get(type); } }业务类加上@PayType
@Service @Slf4j @PayType ( PayTypeEnum .ZFB ) public class AliService implements PayService { public Boolean pay ( String type ) { log .info ( "调用阿里支付={}" , type ) ; return true ; } }
import com .example .demo .strategy2 .PayType ; import lombok .extern .slf4j .Slf4j ; import org .springframework .stereotype .Service ; @Service @Slf4j @PayType ( PayTypeEnum .WX ) public class WxServiceA implements PayService { @Override public Boolean pay ( String type ) { log .info ( "调用微信支付={}" , type ) ; return true ; } }定义一个控制器测试
import com .example .demo .celuemoshi .StrategyFactory ; import org .springframework .web .bind .annotation .GetMapping ; import org .springframework .web .bind .annotation .PathVariable ; import org .springframework .web .bind .annotation .RestController ; @RestController public class PayController { @GetMapping ( "pay/{type}" ) public boolean pay ( @PathVariable ( "type" ) String type ) { StrategyFactory .getService ( type ) ; return true ; } }测试结果
测试微信支付:http://localhost:10001/pay/wx
测试阿里支付:http://localhost:10001/pay/zfb
原文地址:https://HdhCmsTesttoutiao测试数据/article/7160661452180226573/
查看更多关于基于BeanPostProcessor接口+自定义注解玩转策略模式的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://www.haodehen.cn/did193725