- 创建注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Match {
String value();
}
- 处理 match 的工具类
import com.google.common.collect.Maps;
import org.apache.commons.collections4.MapUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
/**
* @date:2024/3/5
*/
@Component
public class HandlerMatcher {
private LazyMap<Class, Map<String, Object>> handlerPool;
private Matcher equalMatcher;
@Resource
private ApplicationContext applicationContext;
public HandlerMatcher(ApplicationContext applicationContext) {
this.handlerPool = new NamelessClass();
this.equalMatcher = new DefaultMatcher(null);
this.applicationContext = applicationContext;
}
public <T> T match(Class<T> targetClass, String key) {
return this.match(targetClass, key, this.equalMatcher);
}
public <T> T match(Class<T> handlerClass, String key, Matcher matcher) {
Map<String, Object> map =this.handlerPool.get(handlerClass);
if (MapUtils.isEmpty(map)) {
return null;
} else {
return (T) matcher.match(map, key);
}
}
private <T> Map<String, T> getHandlers(Class<T> contract) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Map<String, T> handlerMap = Maps.newHashMap();
Map<String, T> beanMap = this.applicationContext.getBeansOfType(contract);
Iterator var4 = beanMap.entrySet().iterator();
while (var4.hasNext()) {
Map.Entry<String, T> entry = (Map.Entry) var4.next();
T handler = entry.getValue();
Class clazz = !AopUtils.isAopProxy(handler) && !AopUtils.isCglibProxy(handler) ? handler.getClass() : AopUtils.getTargetClass(handler);
Match match = (Match) clazz.getAnnotation(Match.class);
if (match != null) {
handlerMap.put(match.value(), handler);
}
}
return handlerMap;
}
private class DefaultMatcher implements Matcher<Object, Object> {
private DefaultMatcher() {
}
public DefaultMatcher(NamelessClass namelessClass) {
}
@Override
public Object match(Map<Object, Object> map, Object key) {
return map.get(key);
}
}
class NamelessClass extends LazyMap<Class, Map<String, Object>> {
NamelessClass() {
}
@Override
protected Map<String, Object> load(Class key) {
try {
return HandlerMatcher.this.getHandlers(key);
} catch (Exception var3) {
throw new RuntimeException(var3);
}
}
}
}
- LazyMap 类
public abstract class LazyMap<K, V> {
private ConcurrentMap<K, V> map = Maps.newConcurrentMap();
public LazyMap() {
}
public V get(K key) {
V value = this.map.get(key);
if (value != null) {
return value;
} else {
value = this.load(key);
V existsValue = value == null ? null : this.map.putIfAbsent(key, value);
return existsValue == null ? value : existsValue;
}
}
protected abstract V load(K var1);
}
- 适配方法接口
public interface Matcher<T, F> {
T match(Map<Object, Object> var1, F var2);
}
- 定义适配器接口
public interface TemplateBuilderInterface {
String build(String Type);
}
- 实现适配器的具体类
@Match("xml")
public class XmlBuilderInterface implements TemplateBuilderInterface {
@Override
public String build(String Type) {
return "xml";
}
}
@Match("json")
public class JsonBuilderInterface implements TemplateBuilderInterface {
@Override
public String build(String Type) {
return "json";
}
}
- 调用方法
@Service
public class MatchService {
@Resource
private HandlerMatcher handlerMatcher;
public String match(String content,String type){
TemplateBuilderInterface builder = handlerMatcher.match(TemplateBuilderInterface.class,type);
return builder.build(content);
}
}
- 测试 controller
@RequestMapping("match")
@ResponseBody
public String match(String type) {
return matchService.match("test",type);
}
- 演示效果:
请求:ip:port/test/match?type=json
返回: json
请求:ip:port/test/match?type=xml
返回:xml