网站怎么适配移动端,在线查看网站源码,灯饰网站建设图片,建设网站需要了解些什么问题文章目录 前言1. 声明注解2. 使用 Spring 的工厂拓展3. 收集策略4. 完整的代码后记 前言
需求#xff1a; 用key找到对应的方法实现。使用注解的形式增量开发。
MyComponent
public class Sample1 {MyMethod(key key1)public String test2() {return She… 文章目录 前言1. 声明注解2. 使用 Spring 的工厂拓展3. 收集策略4. 完整的代码后记 前言
需求 用key找到对应的方法实现。使用注解的形式增量开发。
MyComponent
public class Sample1 {MyMethod(key key1)public String test2() {return Shenzhen;}
}任意时刻都能通过key来进行依赖查找 Testpublic void test() {Assert.notNull(myBeanFactory.getMethod(key1), key1对应的方法不能为空);}实现思路
声明自己的类注解并要求被 Spring 收集声明自己的方法注解确保可以通过反射获取借 Spring 的能力容器启动收集bean完成后把bean列表交给自己用于自己的收集策略。
1. 声明注解
类注解
Target({ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
Documented
// 继承Spring的注解确保类能被Spring扫描
Component
public interface MyComponent {AliasFor(annotation Component.class)String value() default ;
}方法注解
Target({ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
Documented
public interface MyMethod {// 用于依赖查找的keyString key();
}2. 使用 Spring 的工厂拓展
找到我们用注解标记的类、方法Spring 收集完bean之后提供了拓展点供我们遍历这些bean。
BeanFactoryPostProcessor 接口其中 ConfigurableListableBeanFactory beanFactory 提供了容器
Component
public class MyBeanFactory implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 找到所有注解标记的beanMapString, Object beanMap beanFactory.getBeansWithAnnotation(MyComponent.class);beanMap.forEach((beanName, bean) - {// 收集bean中用注解标记的方法 (方法先省略)// collectMethod(bean);});}
}3. 收集策略
收集策略可以很简单这里就用一个Map收集用Spring的AnnotationUtils.findAnnotation(method, MyMethod.class) 命中标识的方法如果命中则拿到注解中的key收集key和Method的映射关系 // 自己的容器private static final MapString, Method METHOD_MAP new HashMap();public Method getMethod(String key) {return METHOD_MAP.get(key);}private void collectMethod(Object bean) {Method[] methods bean.getClass().getDeclaredMethods();Arrays.stream(methods)// 过滤 只要MyMethod标识的方法 .filter(method - Objects.nonNull(getAnnotation(method)))// 收集 通过MyMethod的注解key绑定依赖关系放到自己的容器.forEach(method - METHOD_MAP.putIfAbsent(getAnnotation(method).key(), method));}private static MyMethod getAnnotation(Method method) {return AnnotationUtils.findAnnotation(method, MyMethod.class);}
4. 完整的代码
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;Component
public class MyBeanFactory implements BeanFactoryPostProcessor {private static final ConcurrentHashMapString, Method METHOD_MAP new ConcurrentHashMap();Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 从Spring容器中获取所有MyControllerMapString, Object beanMap beanFactory.getBeansWithAnnotation(MyComponent.class);beanMap.forEach((beanName, bean) - {// 收集bean里面的所有可用方法collectMethod(bean);});}private void collectMethod(Object bean) {Method[] methods bean.getClass().getDeclaredMethods();Arrays.stream(methods)// 过滤 只要MyMethod标识的方法 .filter(method - Objects.nonNull(getAnnotation(method)))// 收集 通过MyMethod的注解key绑定依赖关系放到自己的容器.forEach(method - METHOD_MAP.putIfAbsent(getAnnotation(method).key(), method));}private static MyMethod getAnnotation(Method method) {return AnnotationUtils.findAnnotation(method, MyMethod.class);}public Method getMethod(String key) {return METHOD_MAP.get(key);}
}后记
记录下用到的 Spring 的 api 和工具 一个核心的接口方法获取bean容器 BeanFactoryPostProcessor#postProcessBeanFactory 获取指定注解修饰的类 ConfigurableListableBeanFactory#getBeansWithAnnotation 获取方法上的注解内容 AnnotationUtils#findAnnotation