您好,登录后才能下订单哦!
不懂使用Spring中BeanPostProcessor如何实现工厂模式?其实想解决这个问题也不难,下面让小编带着大家一起学习怎么去解决,希望大家阅读完这篇文章后大所收获。
最近学习Spring的源码,发现一个利器BeanPostProcessor。这个后置处理器可以在bean初始化前后对bean进行操作。我们可以在初始化的时候对自己想要的bean进行缓存,进而实现自己需要处理的逻辑。
背景
当我们需要根据类型调用接口不同实现的时候,我们可以使用工厂模式实现。下面说下博主遇到过的两次需要使用工厂的场景。
场景一:
当有一个模块,我们需要根据数据库的类型实现不同的的sql。我们此时需要定义一个接口然后每一种数据库实现不同的sql。在调用时根据当前的数据库类型调用对应的实现类。
场景二:
我们业务需要对接不同的传感器设备,但是总体业务逻辑就是获取数据,发送心跳。每一种设备的数据协议又不一样。所以需要使用工厂,根据不同的设备调用对应的实现类。
工厂模式
静态工厂
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:54
 * @Version
 **/
@Service
public class HandlerService1 {
  public <T> void handle(Constant.HandlerType handlerType, T dataDO) {
    IHandler handler = null;
    if(handlerType.getType().intValue() == Constant.HandlerType.HANDLE_TYEP_1.getType()){
      handler = new Type1Handler();
    }else if(handlerType.getType().intValue() == Constant.HandlerType.HANDLE_TYEP_2.getType()){
      handler = new Type2Handler();
    }else if(handlerType.getType().intValue() == Constant.HandlerType.HANDLE_TYEP_3.getType()){
      handler = new Type3Handler();
    }else if(handlerType.getType().intValue() == Constant.HandlerType.HANDLE_TYEP_4.getType()){
      handler = new Type4Handler();
    }else{
      throw new RuntimeException("类型错误");
    }
    handler.handle(dataDO);
  }
}动态工厂,通过class实现
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:54
 * @Version
 **/
@Service
public class HandlerService2 {
  public <T,H extends IHandler> void handle(Class<H> clzz, T dataDO) throws IllegalAccessException, InstantiationException {
    IHandler handler = clzz.newInstance();
    handler.handle(dataDO);
  }
}进入主题
BeanPostProcessor实现相同接口的不同实现bean的工厂
首先定义一个注解,后续用来标示bean的处理类型
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Handler {
  @AliasFor(annotation = Component.class)
  String value() default "";
  /**
   * 业务处理类型
   * @return
   */
  Constant.HandlerType handlerType();
}处理类型
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:25
 * @Version
 **/
public class Constant {
  public enum HandlerType{
    HANDLE_TYEP_1(1),
    HANDLE_TYEP_2(2),
    HANDLE_TYEP_3(3),
    HANDLE_TYEP_4(4);
    private Integer type;
    HandlerType(Integer type) {
      this.type = type;
    }
    public Integer getType() {
      return type;
    }
  }
}定义接口处理
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:29
 * @Version
 **/
public interface IHandler<T> {
  void handle(T data);
}BeanPostProcessor实现对bean后置处理。通过注解的类型缓存bean对象。
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:29
 * @Version
 **/
@Service
public class HandleService implements BeanPostProcessor {
  private Map<Integer,IHandler> reportDataHandlerMap = new ConcurrentHashMap<>();
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if(bean instanceof IHandler){
      Handler[] reportHandlers = bean.getClass().getAnnotationsByType(Handler.class);
      if(reportHandlers == null || reportHandlers.length == 0){
        return bean;
      }
      Handler reportHandler = reportHandlers[0];
      reportDataHandlerMap.put(reportHandler.handlerType().getType(), (IHandler) bean);
    }
    return bean;
  }
  public <T> void handle(Constant.HandlerType handlerType, T dataDO) {
    IHandler reportDataHandler = reportDataHandlerMap.get(handlerType.getType());
    if(reportDataHandler == null){
      throw new RuntimeException("类型错误");
    }
    reportDataHandler.handle(dataDO);
  }
}自定义处理器实现,每一种实现一次。
/**
 * @Description
 * @Author Singh
 * @Date 2020-07-06 21:32
 * @Version
 **/
@Handler(handlerType = Constant.HandlerType.HANDLE_TYEP_1 )
public class Type1Handler implements IHandler<String>{
  @Override
  public void handle(String data) {
  }
}感谢你能够认真阅读完这篇文章,希望小编分享使用Spring中BeanPostProcessor如何实现工厂模式内容对大家有帮助,同时也希望大家多多支持亿速云,关注亿速云行业资讯频道,遇到问题就找亿速云,详细的解决方法等着你来学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。