springboot如何获取接口下所有实现类

目录
  • springboot获取接口下所有实现类
  • springboot动态调用实现类
    • 1、添加接口
    • 2、创建实现类
    • 3、获取实现类的相关接口

springboot获取接口下所有实现类

首先定义一个接口

public interface LoginUserService {
    /**
     * 判断手机号是否允许登录
     *
     * @param phone 手机号
     * @return 是否允许
     */
    boolean hasUser(String phone) throws ServiceException;
    /**
     * 通过Phone获取用户信息
     *
     * @param phone 手机号
     * @return 用户信息
     */
    UserDTO getUserInfoByPhone(String phone) throws LoginException;
}

编写实现类,三个

在这点我的登陆接口上继承了LoginUserService

在运行时需要通过查找bean,但是又不知道具体需要使用哪个bean,在这里自定义一个注解来标记使用哪个实现类

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OrgainzationType {
    LoginTypeEnum value();
}

在实现类上标记具体类型

通过service使用bean进行查询想要的实现类

@Slf4j
@Service
public class LoginServiceImpl implements LoginService, InitializingBean, ApplicationContextAware {
    private ApplicationContext applicationContext;
    protected Map<LoginTypeEnum, LoginUserService> serviceMap = new HashMap<>();
    @Override
    public void afterPropertiesSet() throws Exception {
        // 查找所有LoginUserService接口的实现类
        Map<String, LoginUserService> beanMap = applicationContext.getBeansOfType(LoginUserService.class);
        for (LoginUserService impl : beanMap.values()) {
        	// 获取注解上的类型
            OrgainzationType annotation = AnnotationUtils.findAnnotation(impl.getClass(),OrgainzationType.class);
            // 如果没有添加注解则不需要使用
            if (Objects.isNull(annotation)) {
                continue;
            }
            serviceMap.put(annotation.value(), impl);
        }
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
 }

运行时的类

springboot动态调用实现类

因为项目需要,我们有一个功能的接口UserReader。其他的类都是实现这个接口。那么会有多个实现UserReader接口的实现类。现在需要在程序 中动态的去调用不通实现类中的方法getUser()。

下面既是功能实现代码:

1、添加接口

package com.example.mavenceshi.service;
/**
 * @author by CLP
 * @Classname UserReader
 * @Description
 * @Date 2020/9/8 15:16
 */
public interface UserReader {
    String getUser();
}

2、创建实现类

1)实现类UserReaderImpl1

package com.example.mavenceshi.service.impl;
import com.example.mavenceshi.service.UserReader;
import org.springframework.stereotype.Component;
/**
 * @author by CLP
 * @Classname UserReader1
 * @Description
 * @Date 2020/9/8 15:17
 */
@Component
public class UserReaderImpl1 implements UserReader {
    @Override
    public String getUser() {
           return "访问的UserReaderImpl1";
    }
}

2)实现类 UserReaderImpl2

package com.example.mavenceshi.service.impl;
import com.example.mavenceshi.service.UserReader;
import org.springframework.stereotype.Component;
/**
 * @author by CLP
 * @Classname UserReaderImpl2
 * @Description
 * @Date 2020/9/8 15:18
 */
@Component
public class UserReaderImpl2 implements UserReader {
    @Override
    public String getUser() {
          return "访问的UserReaderImpl2";
    }
}

3、获取实现类的相关接口

package com.example.mavenceshi.config;
import com.example.mavenceshi.service.UserReader;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * @author by CLP
 * @Classname BeanConfig
 * @Description
 * @Date 2020/9/8 15:28
 */
@Component
public class BeanConfig implements InitializingBean, ApplicationContextAware {
    private Map<String, UserReader> queryServiceImplMap = new HashMap<>();
    private ApplicationContext applicationContext;
    public UserReader createQueryService(String type) {
        UserReader userReader = queryServiceImplMap.get(type);
        if (userReader == null) {
            return queryServiceImplMap.get("UserReader1Impl");
        }
        return userReader;
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, UserReader> beanMap = applicationContext.getBeansOfType(UserReader.class);
        //遍历该接口的所有实现,将其放入map中
        for (UserReader serviceImpl : beanMap.values()) {
            queryServiceImplMap.put(serviceImpl.getClass().getSimpleName(), serviceImpl);
        }
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

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

(0)

相关推荐

  • SpringBoot同一接口多个实现类配置的实例详解

    SpringBoot项目中可能出现一个接口有多个实现类的情况,如果不进行配置,注入接口时编译器不知道要注入哪个实现类就会报错,因此需要进行配置.以下进行举例: 接口如下: public interface NoticeService { public String noticeUser(Long id); } 两个实现类如下: @Service public class NoticeServiceImpl1 implements NoticeService { public String not

  • 使用Springboot根据配置文件动态注入接口实现类

    Springboot根据配置文件动态注入接口实现类 需求 最近在做一个Springboot项目,需要面向不同需求的客户,但是为了方便管理分支,需要将不同客户的需求都写到同一套代码中,根据不同客户实例化对应的实现类. 实现 为了尽量不修改代码,少做不必要的逻辑判断,我们考虑为不同客户写不同的Service,然后根据配置参数实例化对应的Service.这样就遇到了需要根据配置文件实现不同类的需求. 针对这一需求大致有两种实现方式.但是针对我的需求,能用的只有第二种,但还是想将第一种一起总结一下. 两

  • springboot接口多实现类选择性注入解决方案

    目录 一.问题的描述 二.相对低级解决方案 2.1.方案一:使用@Primary注解 2.2.方案二:使用@Resource注解 2.3.方案三:使用@Qualifier注解 三.相对高级的解决方案 一.问题的描述 在实际的系统应用开发中我经常会遇到这样的一类需求,相信大家在工作中也会经常遇到: 同一个系统在多个省份部署. 一个业务在北京是一种实现方式,是基于北京用户的需求. 同样的业务在上海是另外一种实现方式,与北京的实现方式大同小异 遇到这样的需求,我们通常会定义一个业务实现的接口,比如:

  • Java SpringBoot 获取接口实现类汇总

    目录 前言 一.获取接口的所有实现类 1.枚举 2.业务接口 2.1 实现类 3.ApplicationContextAware接口实现类 4.获取到所有实现类使用 前言 有时候,根据业务逻辑的需求,需要获取到某个接口的所有实现类,然后根据业务类型来执行不同的实现类方法.有点类似策略模式. 如果没有用到 Spring的话,可以使用 ServiceLoaderl类JDK自带的一个类加载器(其他框架的SPI机制也是可以实现). ServiceLoader<MyInterface> loader =

  • 使用SpringBoot根据配置注入接口的不同实现类(代码演示)

    目录 一.引言 二.代码演示 1.问题描述 2.解决方案 2.1使用@Autowired的时候将接口变量名改为实现类的限定名 2.2 使用@Autowired配合@Qualifier指定限定名注入实现类 2.3@ConditionalOnProperty 三.总结 一.引言 我们在使用springboot进行开发的时候经常用到@Autowired和@Resource进行依赖注入,但是当我们一个接口对应多个不同的实现类的时候如果不进行一下配置项目启动时就会报错,那么怎么根据不同的需求注入不同的类型

  • springboot如何获取接口下所有实现类

    目录 springboot获取接口下所有实现类 springboot动态调用实现类 1.添加接口 2.创建实现类 3.获取实现类的相关接口 springboot获取接口下所有实现类 首先定义一个接口 public interface LoginUserService { /** * 判断手机号是否允许登录 * * @param phone 手机号 * @return 是否允许 */ boolean hasUser(String phone) throws ServiceException; /*

  • 使用spring动态获取接口的不同实现类

    目录 spring动态获取接口的不同实现类 当时想到了两种解决办法 获取某接口所有实现类 正文 结果 spring动态获取接口的不同实现类 最近做项目,有个需求是和外部对接,从接口获取新闻数据,把数据和缓存中的数据对比,多了的添加到数据库,少了的删掉. 接口有两个,一开始我是在业务类里写了两个方法,代码太长,简单说就是两个部分: public Object saveANews() { //1.获取A接口新闻列表 //2.和缓存对比,存数据到数据库 } public Object saveBNew

  • springboot如何获取相对路径文件夹下静态资源的方法

    今日遇到一个问题:springboot需要获取到一个自定义名称文件夹下的静态资源(图片等),并且文件夹的路径不在classPath下面,而是一个相对路径. 一开始使用修改配置文件的方式: # 配置静态资源访问前缀 spring.mvc.static-path-pattern=*/** # 配置静态资源路径,默认配置失效 spring.resources.static-locations=../upload 发现并不行,无法解析出相对路径. 后面通过自定义静态资源映射配置类实现了: @Config

  • Java获取接口所有实现类的方式详解

    有时候,根据业务逻辑的需求,我们想要获取到某个接口的所有实现类.在这里大致介绍两种方式: 1.借助Spring容器实现 Spring作为一个容器,管理着一个项目中所有经过配置的Java类(xml配置文件或Annotation方式).如果某个接口的所有实现类均被Spring托管了,那么通过Spring就可以很简单的返回这些实现类. import org.springframework.beans.BeansException; import org.springframework.context.

  • springboot项目打成jar包后无法获取static下的静态资源文件的问题分析

    springboot 后端项目 做某个功能时 需要读取根目录下的.doc文件,具体项目中路径如下: 开始是通过绝对路径读取文档,在本地没有任何问题. 但是 讲项目打成jar包 部署到测试环境发现无论怎样都读取不到,然后在本地运行jar包出现同样的情况. 捕获异常:java.io.FileNotFoundException [org.apache.ibatis.session.defaults.DefaultSqlSession@55b40849] java.io.FileNotFoundExce

  • java反射获取包下所有类的操作

    我就废话不多说了,大家还是直接看代码吧~ public static void main(String[] args) { try { // 获取包名下所有类 Set<Class<?>> classes = getClasses("com"); for(Class c:classes){ // 打印有RestController 的类 if(c.isAnnotationPresent(RestController.class)){ System.out.prin

  • 如何获取包下所有类中的注解的值(java工具类)

    获取包下所有类中注解的值 作用: 这个工具类主要的作用就是获取类中的注解的值. 应用场景: 做权限的时候获取@RequestMapping();的值,自动添加到数据库中. /** * getRequestMappingValue方法描述: * 作者:thh * 日期:2016年7月18日 下午5:41:00 * 异常对象:@param packageName * 异常对象:@return */ public static List<String> getRequestMappingValue(

  • springboot打成jar后获取classpath下文件失败的解决方案

    springboot打成jar后获取classpath下文件 代码如下: ClassPathResource resource = new ClassPathResource("app.keystore"); File file = resource.getFile(); FileUtils.readLines(file).forEach(System.out::println); 解决方式如下: 1. Spring framework String data = "&quo

随机推荐