springboot自定义注解实现适配器模式

  1. 创建注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Match {
    String value();
}
  1. 处理 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);
            }
        }
    }

}
  1. 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);
}
  1. 适配方法接口
public interface Matcher<T, F> {
    T match(Map<Object, Object> var1, F var2);
}
  1. 定义适配器接口
public interface TemplateBuilderInterface {
    String build(String Type);
}
  1. 实现适配器的具体类
@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";
    }
}
  1. 调用方法
@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);
    }
}
  1. 测试 controller
    @RequestMapping("match")
    @ResponseBody
    public String match(String type) {
        return matchService.match("test",type);
    }
  1. 演示效果:

请求:ip:port/test/match?type=json
返回: json

请求:ip:port/test/match?type=xml
返回:xml

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荼白z

感谢老板请我喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值