自定义注解@interface还是很jiao的,先来一段代码
//@Documented
//@Inherited
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE,ElementType.METHOD})
public @interface Test {
String value() default "Hello World!";
}
如上所示的代码有四个注解,起内涵可以百度查询一下,查询之后对该代码的理解应该就到位了,在了解这个流程之后就可以开始以下步骤
1.在main方法里对注解进行解析,取出其中的值
例
@Test
public class Main {
public static void main(String[] args) throws ClassNotFoundException{
if(Main.class.isAnnotationPresent(Test.class)){
Testd d=Main.class.getAnnotation(Test.class);
System.out.println(d.ss());
}
}
}
这里的主方法实现了取值,流程核心为两步
1.判定是否注解
2.实例化再取值
上期我们的自定义注解还不太完善,接下来是就是完善后的了
滴滴滴滴滴:::::在取值后基本都会有疑问,这个值用来干嘛,我想实现其自动就做了某项功能,和这个值在这里有什么关系呢,下面就来分析一下
上代码:
滴滴滴滴滴:----->
@Autowired
private com.rjkj.service.RabbitUse RabbitUse;
/**
* 测试rabbitmq的发送请求
*/
@Queue(queue = "队列呀",routingkey = "color",exchange = "我是发送的颜色")
@GetMapping("/sendrabbit")
public String send(String message){
return RabbitUse.sendrabbit("wasdfg");
}
/**
* 接收消息确认
* @return
*/
@Queue(queue = "队列呀",routingkey = "color",exchange = "我是接收的颜色")
@GetMapping("/getrabbit")
public List<String> getrabbit(){
return RabbitUse.getrabbit();
}
比如这个,在我们的新版自定义注解里是这样的:
@Target(value = {ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Queue {
//队列名称
String queue() default "queue_name";
//路由
String routingkey() default "routingkey";
//交换机声明
String exchange() default "exchange";
}
这里有三个属性,我们在上一段代码中用到了这些属性,接下来我们就看实现流程是怎样的,还是继续上代码:
@Value("${spring.rabbitmq.pacakage}")
private String pacakage;
public Map<String, Map<String, ParsingEntity>> queueParsing(){
Reflections reflections = new Reflections(pacakage, Arrays.asList(
new SubTypesScanner(false)//允许getAllTypes获取所有Object的子类, 不设置为false则 getAllTypes 会报错.默认为true.
,new MethodParameterNamesScanner()//设置方法参数名称 扫描器,否则调用getConstructorParamNames 会报错
,new MethodAnnotationsScanner() //设置方法注解 扫描器, 否则getConstructorsAnnotatedWith,getMethodsAnnotatedWith 会报错
,new MemberUsageScanner() //设置 member 扫描器,否则 getMethodUsage 会报错, 不推荐使用,有可能会报错 Caused by: java.lang.ClassCastException: javassist.bytecode.InterfaceMethodrefInfo cannot be cast to javassist.bytecode.MethodrefInfo
,new TypeAnnotationsScanner()//设置类注解 扫描器 ,否则 getTypesAnnotatedWith 会报错
));
Set<Class<?>> annottypes=reflections.getTypesAnnotatedWith(Queue.class);
// 存放url和ExecutorBean的对应关系
Map<String, Map<String, ParsingEntity>> mapp = new HashMap<String, Map<String, ParsingEntity>>();
Map<String, ParsingEntity> map = new HashMap<>();
for (Class classes : annottypes) {
// 得到该类下面的所有方法
Method[] methods = classes.getDeclaredMethods();
for (Method f : methods) {
if (f.isAnnotationPresent(Queue.class)) {
ParsingEntity parsingEntity = new ParsingEntity();
parsingEntity.setQueue(f.getAnnotation(Queue.class).queue());
parsingEntity.setExchange(f.getAnnotation(Queue.class).exchange());
parsingEntity.setRoutingkey(f.getAnnotation(Queue.class).routingkey());
map.put(f.getName(), parsingEntity);
}
}
mapp.put(classes.getName(),map);
}
return mapp;
}
在这段代码中,不仔细看真找不到和它相关的数据,但是仔细看看,其中会发现有一个queue.class的字句,那么上面的方法是做什么的呢,这个方法的话其实就是我们一个用来解析自定义注解的工具类,在这个类里这个方法用于解析所有包下的该注解,并将其以map的形式获取发送至我们需要进行业务操作的方法里,这个你可以理解为固定代码,在获取类queue的这里只有一句话,如果还有更多的自定义注解,那么依次继续写入就行了,至于下面的实体装参数嘛,就是对应我们的自定义注解需要的参数,因为实际中会有很多个,所以这里的参数装订就自己照这样子来改一下就ok了,最后我们将解析的数据放在了map里,键值对通过类名,方法外加请求方法就将对应的数据精准的返回了,那么这里的数据我们直接调用这个方法就可以获取了,包括@Value这个注解自己也可以看一下,这是应用于yml配置文件的一个注解,主要作用就是直接赋值,其实理解后也没多复杂,就一个自定义注解,随后将它解析然后返回它的参数再给其他的工具类去使用,这些工具类的话也就是相当于jar包,直接调用接口,只不过是已经封装好了的,本期就到这里,下期有待更新哈,嘀嘀嘀嘀嘀滴滴嘀!!!111111111