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")));
}
运行测试方法时显示:文章来源:https://www.toymoban.com/news/detail-624908.html
测试: father2
test_two场景下调用sayHello:father2文章来源地址https://www.toymoban.com/news/detail-624908.html
到了这里,关于SpringBoot根据注解动态执行类中的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!