SpringBoot根据注解动态执行类中的方法

这篇具有很好参考价值的文章主要介绍了SpringBoot根据注解动态执行类中的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、需求

有一个接口提供了xx的服务,有两个场景分别实现了xx的具体逻辑,标记为xx1和xx2。

然后场景一过来的时候执行xx1逻辑,场景二过来的时候执行xx2逻辑。

2、简单实现

定义一个service层,提供xx的接口。

然后定义两个serviceImpl,@Service(name="")标记不同的名称,分别提供xx的具体实现。

在使用时,通过@Resource(name="")注入两个组件。

接着硬编码,当场景一时调用组件1的xx方法,当场景二时调用组件2的xx方法。

这种方法可读性较高,逻辑也清晰,但是扩展性不高,硬编码的硬伤

3、通过自定义注解的方式

(1)实现方案

首先,构造一个自定义注解@Extension,用于存放场景所需的信息。

其次,定义一个Service接口提供xx服务

然后,定义两个ServiceImpl类实现接口的xx服务,并且标记@Service注解。同时新增@Extension注解,输入场景信息。

接着,定义一个@PostConstruct方法,在方法中读取容器中所有带@Extension注解的示例,将注解的场景信息作为key,示例作为Object放入某个组件ExtRespository的Map中存起来。

最后,请求过来时解析场景信息,从ExtRespository的Map中读取实例信息,通过Function<T,R>函数式编程调用接口的xx方法。

(2)实现示例

1)Extension.java

自定义注解接口

/**
 * 自定义注解
 */
@Retention(RetentionPolicy.RUNTIME) // 作用于运行时
@Target(ElementType.TYPE)   // 作用于类上
@Component
public @interface Extension {
    String bizScene() default "defaultBizScene";
    String useCase() default "defaultUseCase";
}

2)Father.java

模拟Service接口

public interface Father {
    public String sayHello();
}

3)FatherOne.java

模拟ServiceImpl实现类1

@Component
@Extension(bizScene="test", useCase="one")
public class FatherOne implements Father {
    @Override
    public String sayHello() {
        System.out.println("测试: father1");
        return "father1";
    }
}

4)FatherTwo.java

模拟ServiceImpl实现类2

@Component
@Extension(bizScene="test", useCase="two")
public class FatherTwo implements Father{
    @Override
    public String sayHello() {
        System.out.println("测试: father2");
        return "father2";
    }
}

5)ExtInitiator.java

项目启动时的一部分初始化

@Component
public class ExtInitiator {

    @Autowired
    ExtRespository extRespository;

    @Autowired
    private ApplicationContext applicationContext;

    @PostConstruct
    public void init(){
        Map<String, Object> extensionBeans = applicationContext.getBeansWithAnnotation(Extension.class);
        for(Object bean : extensionBeans.values()){
            Class<?> extensionClz = ClassUtils.getUserClass(bean);
            Extension extension = AnnotationUtils.findAnnotation(extensionClz, Extension.class);
            String bizScene = extension.bizScene();
            String useCase = extension.useCase();
            extRespository.getExtRepository().put(bizScene + "_" + useCase, bean);
        }
    }
}

6)ExtRespository.java

组件提供map的存放

@Component
public class ExtRespository {
    private Map<String, Object> extRepository = new HashMap<>();

    public Map<String, Object> getExtRepository(){
        return extRepository;
    }
}

7)Test方法中测试

@Autowired
ExtRespository extRespository;

@Test
public void testExtension() {
    Function<Father, String> exeFunction = extention -> extention.sayHello();

    System.out.println("test_two场景下调用sayHello:" + exeFunction.apply((Father)extRespository.getExtRepository().get("test_two")));
}

运行测试方法时显示:

测试: father2
test_two场景下调用sayHello:father2文章来源地址https://www.toymoban.com/news/detail-624908.html

到了这里,关于SpringBoot根据注解动态执行类中的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • String类中的一些常用方法(JAVA)

    目录 字符串比较方法: boolean equals(Object anObject):  int compareTo(String s): int compareToIgnoreCase(String str) 字符串查找方法: char charAt(int index): int indexOf(int ch):  int indexOf(int ch, int fromIndex): int indexOf(String str): int indexOf(String str, int fromIndex): int lastIndexOf(int ch): int lastIndexOf(in

    2024年02月07日
    浏览(42)
  • C++回调函数 匿名函数,类中的方法做为回调函数

    C++中的回调函数和匿名函数都是函数指针或函数对象的使用形式。下面分别介绍它们的使用方法。 回调函数是一种函数指针,它允许将函数作为参数传递给另一个函数,并在需要时调用它。这种技术通常用于事件处理、异步处理和状态机等应用中。 下面是一个简单的示例,

    2024年02月01日
    浏览(47)
  • Spring事务失效,同一个类中的内部方法调用事务失效

    所谓声明式事务,也就是通过配置的方式,比如通过 配置文件xml或者注解 的方式,来告诉Spring哪些方法需要Spring帮忙管理事务,然后开发者只需要关注业务代码,而事务的事情则由Spring自动帮我们控制。 配置文件的方式 :即在spring.xml文件中进行统一配置,开发者基本不用

    2023年04月18日
    浏览(46)
  • 【Java】在实体类中常用的注解校验

    注解 说明 @Null 只能为null @NotNull(message = “id不能为空”) 必须不为null,可以为空字符串 @Min(value) 必须为一个不小于指定值的数字 @Max(value) 必须为一个不大于指定值的数字 @NotBlank(message = “姓名不能为空”) 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同

    2024年02月04日
    浏览(87)
  • JAVA深化篇_29—— 线程使用之线程联合以及Thread类中的其他常用方法【附有详细说明及代码案例】

    线程联合 当前线程邀请调用方法的线程优先执行,在调用方法的线程执行结束之前,当前线程不能再次执行。线程A在运行期间,可以调用线程B的join()方法,让线程B和线程A联合。这样,线程A就必须等待线程B执行完毕后,才能继续执行。 join方法的使用 join()方法就是指调用该

    2024年02月05日
    浏览(47)
  • 【JAVA原理系列】Java String类中的三个替换方法replaceFirst、replaceAll和replace原理用法示例源码详解

    这里是三种字符串替换方法的原理: replaceFirst() 方法的原理是通过编译给定的正则表达式,然后使用编译后的模式创建一个匹配器对象,将该匹配器应用于目标字符串,并使用给定的替换字符串替换第一个匹配的子字符串。 replaceAll() 方法的原理与 replaceFirst() 类似,也是通过

    2024年04月16日
    浏览(43)
  • Springboot中的@DependsOn注解

    在我的最近的Spring Boot项目中,我遇到了涉及两个Bean的情况,Bean1和Bean2。在初始化过程中,我需要Bean2依赖于Bean1。 其中Spring中的 @DependsOn 注解,允许我指定在创建Bean2之前,Spring应确保Bean1已初始化。 在 Spring Boot 中,您可以使用@DependsOn注解来定义 bean 之间的依赖关系。该注

    2024年01月18日
    浏览(45)
  • 认识SpringBoot中的条件注解

    ✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:认识SpringBoot中的条件注解 📚个人知识库: Leo知识库,欢迎大家访问 大家好,我是L

    2024年02月02日
    浏览(40)
  • 【Java基础教程】(三十八)常用类库篇 · 第八讲:数组操作类——解析Arrays类中的全部操作方法,解锁Java数组操作技巧~

    前言:在学习本文之前,应该先学习并清楚了解Java基础部分的数组相关的概念和知识。 若还不具备学习条件,请先前往学习数组部分的基础知识: 《【Java基础教程】(八)面向对象篇 · 第二讲:Java 数组全面解析——动态与静态初始化、二维数组、方法参数传递、排序与转

    2024年02月15日
    浏览(61)
  • 基于注解切换、Hikari实现的SpringBoot动态数据源(支持JNDI)

    先说效果,要实现方法级别注解切换当前数据源,不设置注解时走默认数据源,同时支持JNDI源。 Spring框架中存在一个抽象类 AbstractRoutingDataSource ,他是一个可以动态选择当前DataSource的路由类,我们就是要从这里入手,重新实现数据源的切换选择逻辑。然后借助注解和切面,

    2024年02月08日
    浏览(79)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包