现有需求:统一程序入口并根据不同条件执行此类不同实现类的方法
关键代码实现:
- 实例注解及其使用基础类
import java.lang.annotation.*;
/**
* @author ccbobe
*/
@Documented
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RoutingClass {
String name() default "";
String[] values() default {};
String version() default "1";
}
/**
* 需要多实现的类
*/
public interface BaseRun {
/**
* 保证需要执行的方法
* @param context
* @return
*/
Context run(Context context);
}
public interface BaseBofore {
/**
* 执行之前操作业务
* @param context
* @return
*/
Context before(Context context);
}
/**
* @author ccbobe
*/
public interface BaseAfter {
/**
* 方法执行之后干活
* @param context
* @return
*/
Context afterRun(Context context);
}
- 从SpringIoc 容器中获取某个实现类实例
private ApplicationContext context;
private ConcurrentHashMap<String, BaseRun> bases = new ConcurrentHashMap<>(32);
private ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
@PostConstruct
public void init(){
//加载指定类型实现并缓存
context.getBeansWithAnnotation(RoutingClass.class).forEach((k,v)->{
RoutingClass routingClass = v.getClass().getAnnotation(RoutingClass.class);
if (BaseRun.class.isAssignableFrom(v.getClass())) {
bases.put(routingClass.name(), (BaseRun ) v);
}
});
}
- 使用此方法
/**
* 传递资源
* @author ccbobe
*/
@Data
public class Context<Before,U,After> {
/**
* 资源ID
*/
private String id;
/**
* 方法类型
*/
private String name;
/**
* 方法名
*/
private String method;
/**
* 数据之前处理
*/
private Before before;
/**
* 返回数据结果
*/
private U result;
/**
* 数据之后处理
*/
private After after;
}
//关键使用情况
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author ccbobe
*/
@Component
public class RunProcess implements ApplicationContextAware {
private ApplicationContext context;
private ConcurrentHashMap<String, BaseRun> bases = new ConcurrentHashMap<>(32);
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
@PostConstruct
public void init(){
context.getBeansWithAnnotation(RoutingClass.class).forEach((k,v)->{
RoutingClass routingClass = v.getClass().getAnnotation(RoutingClass.class);
if (BaseRun.class.isAssignableFrom(v.getClass())) {
bases.put(routingClass.name(), (BaseRun ) v);
}
});
}
//关键使用代码
public Context run(Context context){
BaseRun baseRun = bases.get(context.getName());
if (baseRun instanceof BaseBofore){
Context before = ((BaseBofore) baseRun).before(context);
context.setBefore(before.getBefore());
}
Context run = baseRun.run(context);
context.setResult(run.getResult());
if (baseRun instanceof BaseAfter){
Context after = ((BaseAfter) baseRun).afterRun(context);
context.setAfter(after.getAfter());
}
return context;
}
}
- 简单测试用例
import org.springframework.stereotype.Component;
@RoutingClass(name = "TestBase",values = {"add"},version = "1")
@Component
public class TestBase implements BaseRun {
@Override
public Context run(Context context) {
return context;
}
}
/**
* @author ccbobe
*/
@RoutingClass(name = "helloBase",values = {""},version = "1")
@Component
public class HelloBase implements BaseRun,BaseBofore,BaseAfter {
@Override
public Context before(Context context) {
System.out.println("before.....");
context.setBefore("before");
return context;
}
@Override
public Context run(Context context) {
System.out.println("afterRun.....");
context.setResult("run");
return context;
}
@Override
public Context afterRun(Context context) {
System.out.println("afterRun.....");
context.setAfter("afterRun");
return context;
}
}
@Autowired
private RunProcess process;
@RequestMapping("hello")
public Context hello(Context context){
context.setId(UUID.randomUUID().toString().replace("-","").toUpperCase());
context.setName("helloBase");
Context run = process.run(context);
return run;
}
@RequestMapping("test")
public Context testBase(Context context){
context.setId(UUID.randomUUID().toString().replace("-","").toUpperCase());
context.setName("TestBase");
Context run = process.run(context);
return run;
}