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实现


注解

注解

 

posted @ 2019-04-02 20:10  花花牛  阅读(1710)  评论(0编辑  收藏  举报