Spring Bean自動註冊的實現方案

這裏Spring管理的Bean,可以認爲是一個個的Service,每個Service都是一個服務接口

 

自動註冊Service的好處:

1、根據指定的name/id獲取對應的Service,實現簡單工廠

2、服務自動註冊到Map中,集中管理

 

方案1:通過接口實現


 

1、聲明接口:定義接口的方法,這裏用到的泛型可以根據實際需要忽略

1 /**
2  * @Description: 資金請求處理 接口
3  * -- 資金類操作的公共接口
4  * @author: lishh
5  * @Date: 2019/1/16 20:40
6  */
7 public interface IFundReqHandleService<Req extends BaseRequest, Resp extends BaseResponse, DO extends CommonDO> {
8     //接口定義忽略...
9 }

 

2、接口實現

實現舉例:注意:每個實現類都定義了一個final的值,作爲它的id,以後拿着這個id獲取這個服務

/**
 * @Description: 入金
 * @author: lishh
 * @Date: 2019/1/4 15:55
 */
@Service
public class FundinServiceImpl implements IFundReqHandleService<FundinReq, FundinResp, Fundin> {
    private static Logger logger = LoggerFactory.getLogger(FundinServiceImpl.class);
    private final RequestTypeEnum fundReqType = RequestTypeEnum.FUND_IN;

    @Autowired
    private FundinMapper fundinMapper;

    
    //...略....
}

 

3、定義獲取服務的工廠類:這裏的RequestTypeEnum定義爲枚舉是爲了可讀性更好,使用字符串也可以

 1 /**
 2  * @Description: 資金操作服務 工廠
 3  * @author: lishh
 4  * @Date: 2019/1/4 17:39
 5  */
 6 public interface IFundServiceFactory {
 7 
 8     /**
 9      * 根據請求類型 獲取對應的handler
10      *
11      * @param fundType
12      * @return
13      */
14     IFundReqHandleService getService(RequestTypeEnum fundType);
15 }

 

4、實現工廠類,提供服務獲取的實現:代碼很簡單,關鍵就是注入Map<String, IFundReqHandleService> fundFlowMap;

 1 /**
 2  * @Description: 資金操作服務 工廠
 3  * @author: lishh
 4  * @Date: 2019/1/4 17:44
 5  */
 6 @Component("fundServiceFactory")
 7 public class FundServiceFactoryImpl implements IFundServiceFactory, InitializingBean {
 8     private static Logger logger = LoggerFactory.getLogger(FundServiceFactoryImpl.class);
 9 
10     /**
11      * 注入實現IReqHandleService接口的所有服務
12      * key: service name
13      * value:服務引用
14      */
15     @Autowired
16     Map<String, IFundReqHandleService> fundFlowMap;
17 
18     /**
19      * 資金操作handler Map
20      * key:服務類型
21      * value:服務引用
22      */
23     private Map<RequestTypeEnum, IFundReqHandleService> serviceMap = new ConcurrentHashMap<>();
24 
25     /**
26      * 獲取服務
27      *
28      * @param fundType
29      * @return
30      */
31     @Override
32     public IFundReqHandleService getService(RequestTypeEnum fundType) {
33         IFundReqHandleService service = this.getServiceMap().get(fundType);
34         if (null == service) {
35             logger.error("invalid or unsupport fundType:{},current serviceMap:{}",
36                     JSON.toJSONString(fundType),
37                     JSON.toJSONString(this.getServiceMap()));
38         }
39 
40         return service;
41     }
42 
43     /**
44      * 服務自動註冊...
45      *
46      * @throws Exception
47      */
48     @Override
49     public void afterPropertiesSet() throws Exception {
50         for (Map.Entry<String, IFundReqHandleService> entry : fundFlowMap.entrySet()) {
51             RequestTypeEnum reqType = entry.getValue().getReqType();
52             this.getServiceMap().put(reqType, entry.getValue());
53             logger.info("regist service:{}-->{}.current map size:{}", entry.getKey(), reqType.getReqType(), this.getServiceMap().size());
54         }
55     }
56 
57     public Map<RequestTypeEnum, IFundReqHandleService> getServiceMap() {
58         return serviceMap;
59     }
60 
61 }

 

5、使用

很簡單,注入工廠類,提供id給你獲取服務

 1 /**
 2      * 資金類請求處理服務工廠
 3      */
 4     @Resource(name = "fundServiceFactory")
 5     private IFundServiceFactory fundServiceFactory;
 6 
 7 //...略。。。。
 8 
 9  //01、獲取業務處理對象
10             IFundReqHandleService reqHandler = fundServiceFactory.getService(requestType);
11             if (null == reqHandler) {
12                 throw new SysException(ErrorCodeEnum.ACCT_SERVICE_ERROR, "unsupport requestType");
13             }
14 //。。。。調用服務接口,略,...

 

總結:

1、spring注入的理解

2、InitializingBean接口的理解

 

方案2:通過註解annotation實現


註解

註解

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章