詳解使用Spring的BeanPostProcessor優(yōu)雅的實現(xiàn)工廠模式
最近學習Spring的源碼,發(fā)現(xiàn)一個利器BeanPostProcessor。這個后置處理器可以在bean初始化前后對bean進行操作。我們可以在初始化的時候對自己想要的bean進行緩存,進而實現(xiàn)自己需要處理的邏輯。
背景
當我們需要根據(jù)類型調用接口不同實現(xiàn)的時候,我們可以使用工廠模式實現(xiàn)。下面說下博主遇到過的兩次需要使用工廠的場景。
場景一:
當有一個模塊,我們需要根據(jù)數(shù)據(jù)庫的類型實現(xiàn)不同的的sql。我們此時需要定義一個接口然后每一種數(shù)據(jù)庫實現(xiàn)不同的sql。在調用時根據(jù)當前的數(shù)據(jù)庫類型調用對應的實現(xiàn)類。
場景二:
我們業(yè)務需要對接不同的傳感器設備,但是總體業(yè)務邏輯就是獲取數(shù)據(jù),發(fā)送心跳。每一種設備的數(shù)據(jù)協(xié)議又不一樣。所以需要使用工廠,根據(jù)不同的設備調用對應的實現(xiàn)類。
工廠模式
靜態(tài)工廠
/** * @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); } }
動態(tài)工廠,通過class實現(xiàn)
/** * @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實現(xiàn)相同接口的不同實現(xiàn)bean的工廠
首先定義一個注解,后續(xù)用來標示bean的處理類型
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Handler { @AliasFor(annotation = Component.class) String value() default ""; /** * 業(yè)務處理類型 * @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實現(xiàn)對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); } }
自定義處理器實現(xiàn),每一種實現(xiàn)一次。
/** * @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優(yōu)雅的實現(xiàn)工廠模式的文章就介紹到這了,更多相關Spring BeanPostProcessor 工廠模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Spring?BeanPostProcessor后處理器源碼解析
- 關于Spring BeanPostProcessor的執(zhí)行順序
- Spring BeanPostProcessor(后置處理器)的用法
- SpringBoot之通過BeanPostProcessor動態(tài)注入ID生成器案例詳解
- Spring容器的創(chuàng)建過程之如何注冊BeanPostProcessor詳解
- Spring中的后置處理器BeanPostProcessor詳解
- Spring BeanPostProcessor接口使用詳解
- 解析Java的Spring框架的BeanPostProcessor發(fā)布處理器
- spring中BeanPostProcessor的作用和使用注意事項
相關文章
SpringBoot集成ElasticSearch(ES)實現(xiàn)全文搜索功能
Elasticsearch是一個開源的分布式搜索和分析引擎,它被設計用于處理大規(guī)模數(shù)據(jù)集,它提供了一個分布式多用戶能力的全文搜索引擎,本文將給大家介紹SpringBoot集成ElasticSearch(ES)實現(xiàn)全文搜索功能,需要的朋友可以參考下2024-02-02Java redis存Map對象類型數(shù)據(jù)的實現(xiàn)
本文主要介紹了Java redis存Map<String,RedisCustom>對象類型數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-05-05Java 8 Stream.distinct() 列表去重的操作
這篇文章主要介紹了Java 8 Stream.distinct() 列表去重的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12