详解使用Spring的BeanPostProcessor优雅的实现工厂模式
最近学习Spring的源码,发现一个利器BeanPostProcessor。这个后置处理器可以在bean初始化前后对bean进行操作。我们可以在初始化的时候对自己想要的bean进行缓存,进而实现自己需要处理的逻辑。
背景
当我们需要根据类型调用接口不同实现的时候,我们可以使用工厂模式实现。下面说下博主遇到过的两次需要使用工厂的场景。
场景一:
当有一个模块,我们需要根据数据库的类型实现不同的的sql。我们此时需要定义一个接口然后每一种数据库实现不同的sql。在调用时根据当前的数据库类型调用对应的实现类。
场景二:
我们业务需要对接不同的传感器设备,但是总体业务逻辑就是获取数据,发送心跳。每一种设备的数据协议又不一样。所以需要使用工厂,根据不同的设备调用对应的实现类。
工厂模式
静态工厂
/** *@Description *@AuthorSingh *@Date2020-07-0621:54 *@Version **/ @Service publicclassHandlerService1{ publicvoidhandle(Constant.HandlerTypehandlerType,TdataDO){ IHandlerhandler=null; if(handlerType.getType().intValue()==Constant.HandlerType.HANDLE_TYEP_1.getType()){ handler=newType1Handler(); }elseif(handlerType.getType().intValue()==Constant.HandlerType.HANDLE_TYEP_2.getType()){ handler=newType2Handler(); }elseif(handlerType.getType().intValue()==Constant.HandlerType.HANDLE_TYEP_3.getType()){ handler=newType3Handler(); }elseif(handlerType.getType().intValue()==Constant.HandlerType.HANDLE_TYEP_4.getType()){ handler=newType4Handler(); }else{ thrownewRuntimeException("类型错误"); } handler.handle(dataDO); } }
动态工厂,通过class实现
/** *@Description *@AuthorSingh *@Date2020-07-0621:54 *@Version **/ @Service publicclassHandlerService2{ publicvoidhandle(Class clzz,TdataDO)throwsIllegalAccessException,InstantiationException{ IHandlerhandler=clzz.newInstance(); handler.handle(dataDO); } }
进入主题
BeanPostProcessor实现相同接口的不同实现bean的工厂
首先定义一个注解,后续用来标示bean的处理类型
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public@interfaceHandler{ @AliasFor(annotation=Component.class) Stringvalue()default""; /** *业务处理类型 *@return */ Constant.HandlerTypehandlerType(); }
处理类型
/** *@Description *@AuthorSingh *@Date2020-07-0621:25 *@Version **/ publicclassConstant{ publicenumHandlerType{ HANDLE_TYEP_1(1), HANDLE_TYEP_2(2), HANDLE_TYEP_3(3), HANDLE_TYEP_4(4); privateIntegertype; HandlerType(Integertype){ this.type=type; } publicIntegergetType(){ returntype; } } }
定义接口处理
/** *@Description *@AuthorSingh *@Date2020-07-0621:29 *@Version **/ publicinterfaceIHandler{ voidhandle(Tdata); }
BeanPostProcessor实现对bean后置处理。通过注解的类型缓存bean对象。
/** *@Description *@AuthorSingh *@Date2020-07-0621:29 *@Version **/ @Service publicclassHandleServiceimplementsBeanPostProcessor{ privateMapreportDataHandlerMap=newConcurrentHashMap<>(); publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{ if(beaninstanceofIHandler){ Handler[]reportHandlers=bean.getClass().getAnnotationsByType(Handler.class); if(reportHandlers==null||reportHandlers.length==0){ returnbean; } HandlerreportHandler=reportHandlers[0]; reportDataHandlerMap.put(reportHandler.handlerType().getType(),(IHandler)bean); } returnbean; } public voidhandle(Constant.HandlerTypehandlerType,TdataDO){ IHandlerreportDataHandler=reportDataHandlerMap.get(handlerType.getType()); if(reportDataHandler==null){ thrownewRuntimeException("类型错误"); } reportDataHandler.handle(dataDO); } }
自定义处理器实现,每一种实现一次。
/** *@Description *@AuthorSingh *@Date2020-07-0621:32 *@Version **/ @Handler(handlerType=Constant.HandlerType.HANDLE_TYEP_1) publicclassType1HandlerimplementsIHandler{ @Override publicvoidhandle(Stringdata){ } }
到此这篇关于详解使用Spring的BeanPostProcessor优雅的实现工厂模式的文章就介绍到这了,更多相关SpringBeanPostProcessor工厂模式内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!