spring动态发布接口,springboot 动态接口

  spring动态发布接口,springboot 动态接口

  

目录

spring动态获取一个接口的不同实现类。当时想了两个方案来获取一个接口的所有实现类的文本结果。

 

  00-1010最近在做一个项目的时候,有一个需要和外界连接,从接口获取新闻数据,把数据和缓存中的数据进行对比,多加到数据库中,少删。

  有两个接口。起初,我在业务类中编写了两个方法。代码太长。简单来说,就是两部分:

  公共对象saveANews() {//1,获取接口A //2的新闻列表,与缓存进行比较,将数据保存到数据库}公共对象saveBNews() {//1/1,获取B //2的新闻列表,与缓存进行比较,将数据保存到数据库}写完后发现,由于在数据库中操作同一个表,2的一些代码完全相同,只有1。

  必须重用,而且是业务,没必要分开用两种方法,所以我改成这样:

  //业务接口实现方法公共对象save news (newssutilservice) {//1。获取接口新闻列表listnewsvolist=service . query news();//2、与缓存比较,将数据存入数据库}//定义新闻数据接口公共接口newssutilservice { listnewsvo query news();}//接口的两个实现类@ servicepublic类AnewsDataServiceImplements NewssutilService { @ autowiredPrivate NewsdataMapper NewsdataMapper;@ override public listnewsvo query news(){//docking data } } @ servicepublic类bnewsdataserviceimplements newssutilservice { @ override public listnewsvo query news(){//docking data } }//定义工厂类@ service public类newssutilservice factory {/* * * method name 3360 getnewssutilservice * @ param source * @ return */public NewsUtilService getNewsUtilService(String source){ switch(source){ case a 3360 return new ANewsDataServiceImpl();case b : return new BNewsDataServiceImpl();default:return返回null} } } }//控制层调用@ RestControllerPublicClass newsdata controller { @ Resource Private newsdata service newsdata service;@ Resource private NewsUtilServiceFactory工厂;public Object getNewsData(){ String[]sources={ a , b };for(int I=0;一、资料来源。I){ NewsUtilService NewsUtilService=factory . getnewsutilservice(sources[I]);newsdataservice . save news(newsUtilService);}}}我以为这是个大工程,谁知道控制台运行后居然报错了:

  经过一步一步的调试,我终于发现了问题所在:

  在其中一个实现类中注入的映射器未实例化,并且为空。

  一开始我以为是构造函数调用和注入的顺序。查了半天才知道不是。问题是这样的:

  用new关键字实例化的对象不是spring创建的,也不是spring管理的,所以A类实现类中Mapper注入的注释根本不生效!

  但是由于业务需要,需要再次使用该映射器。我该怎么办?

  00-1010 1.将mapper添加到接口的方法参数中,并将mapper作为参数传入,但这真的很奇怪。先不说B类实现类根本不用mapper。

  而且一个接口定义出来后根本不管它的实现类吧,因为实现类的问题去改接口,,,似乎有点非呀。

  于是决定用第二种,修改工厂类变成如下:

  

//定义工厂类@Servicepublic class NewsUtilServiceFactory { @Autowired private ANewsDataServiceImpl aNewsDataServiceImpl; @Autowired private BNewsDataServiceImpl bNewsDataServiceImpl; public NewsUtilService getNewsUtilService(String source){switch(source){case "a":return aNewsDataServiceImpl;case "b":return bNewsDataServiceImpl;default:return null;}}}

代码写出来自己都无语了,先把所有的实现类都实例化出来,在根据输入返回。这不是工厂模式,是商店模式吧。。。但是当时也想不到其他办法,就先这么写了,但一直觉得肯定有其他解决方案,直到今天有空,去查了一下,才发现自己都多low。。。

 

  其实spring可以动态获取实现类的~~~

  

@Servicepublic class NewsUtilServiceFactory {@Autowiredprivate ApplicationContext applicationContext;public NewsUtilService getNewsUtilService(String source){switch(source){case "web":return applicationContext.getBean(WebNewsDataServiceImpl.class);case "oa":return applicationContext.getBean(OANewDataServiceImpl.class);default:return null;}}}

这才是正确写法有木有!

 

  总算弄出来了,赶紧记录下来先~

  

 

  

获取某接口所有实现类

在springboot项目中,为了方便,我们可能需要获取某一个接口下面的所有实现类,根据名称进行匹配使用。

 

  

 

  

正文

1、ServiceLocator.java

 

  

package com.yang.config;import com.yang.workOrder.service.IRootService;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;import java.util.Map;/** * explain:获取应用上下文并获取相应的接口实现类 * * @author yang * @date 2021/1/5 */@Componentpublic class ServiceLocator implements ApplicationContextAware { /** * 用于保存接口实现类名及对应的类 */ private Map<String, IRootService> map; /** * 获取应用上下文并获取相应的接口实现类 * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //根据接口类型返回相应的所有bean map = applicationContext.getBeansOfType(IRootService.class); } /** * 获取所有实现集合 * @return */ public Map<String, IRootService> getMap() { return map; } /** * 获取对应服务 * @param key * @return */ public IRootService getService(String key) { return map.get(key); }}

2、IRootService.java

 

  

package com.yang.workOrder.service;import com.alibaba.fastjson.JSONObject;import com.yang.workOrder.entity.WorkOrder;/** * explain:基础流程操作服务接口 * * @author yang * @date 2021/1/5 */public interface IRootService { /** * 开始流程 * @param workOrder * @return */ boolean startProcess(WorkOrder workOrder);}

3、RootA001ServiceImpl.java

 

  

package com.yang.workOrder.service.impl;import com.alibaba.fastjson.JSONObject;import com.yang.workOrder.entity.WorkOrder;import com.yang.workOrder.service.IRootService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;/** * explain:A_001流程审批实现类 * * @author yang * @date 2021/1/5 */@Service("A_001")public class RootA001ServiceImpl implements IRootService { private static final Logger LOGGER = LoggerFactory.getLogger(RootA001ServiceImpl.class); @Override public boolean startProcess(WorkOrder workOrder) { return false; }}

4、RootA002ServiceImpl.java

 

  

package com.yang.workOrder.service.impl;import com.alibaba.fastjson.JSONObject;import com.yang.workOrder.entity.WorkOrder;import com.yang.workOrder.service.IRootService;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.stereotype.Service;/** * explain:A_002流程审批实现类 * * @author yang * @date 2021/1/5 */@Service("A_002")public class RootA002ServiceImpl implements IRootService { private static final Logger LOGGER = LoggerFactory.getLogger(RootA002ServiceImpl.class); @Override public boolean startProcess(WorkOrder workOrder) { return false; }}

 

  

结果

 

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: