好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

基于BeanPostProcessor接口+自定义注解玩转策略模式

前言

有人说不要用业务类实现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接口+自定义注解玩转策略模式的详细内容...

  阅读:18次