Java自定义注解

Posted 梦Dreamer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java自定义注解相关的知识,希望对你有一定的参考价值。

简介:

    注解是在JDK5.0及以后版本中引入的。他可以用于创建文档,跟踪代码中的依赖性,甚至执行基本的编译时检查,而且还可以作为在spring框架中进行注解式注入Bean属性,用来减少写配置文件。注解是以@+注解名在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解,单值注解、完整注解三类。他们都不会直接影响到程序的语义,只是作为注解存在,可以通过反射机制编程实现对这些元数据的访问。

  java自定义注解的更多介绍,大家可以看下面的系列文章《深入理解Java:注解(Annotation)基本概念》

注解的3中基本类型

  a、标记注解  --没有变量,只有名称标示 例如:@annotation

  b、单一值注解 --在标记注解的基础上提供一段数据。 例如:@annotation("data")

  c、完整注解  --可以包括多个数据成员,每个数据成员由名称和值构成

例如:@annotation(val1="data1",val2="data2")

DEMO

自定义注解的接口声明

package com.ymhj.yas.yoshinoya.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/* 
 * 常用注解说明:  
* 1. RetentionPolicy(保留策略)是一个enum类型,有三个值  
* SOURCE        --  这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译后,Annotation的数据就会消失,并不会保留在编译好的.class文件里 
* CLASS         --  这个Annotation类型的信息保留在程序源码中,同时也会保留在编译好的.class文件里面,在执行的时候,并不会把这一些信息加载到虚拟 机(JVM)中去.注意一下,当你没有设定一个Annotation类型的Retention值时,系统默认值是CLASS。 
* RUNTIME       --  在源码、编译好的.class文件中保留信息,在执行的时候会把这一些信息加载到JVM中去的。 
*  
* 2.ElementType @Target中的ElementType用来指定Annotation类型可以用在哪些元素上 
* TYPE(类型)    -- 在Class,Interface,Enum和Annotation类型上 
* FIELD        -- 属性上 
* METHOD       -- 方法上 
* PARAMETER    -- 参数上 
* CONSTRUCTOR  -- 构造函数上 
* LOCAL_VARIABLE -- 局部变量 
* ANNOTATION_TYPE   -- Annotation类型上 
* PACKAGE           -- 包上 
*  
* 3.Documented    -- 让这个Annotation类型的信息能够显示在API说明文档上;没有添加的话,使用javadoc生成的API文件找不到这个类型生成的信息 
*/  
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation 
	String descraption() default "";

自定义注解的实现

package com.ymhj.yas.yoshinoya.aop;


import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(1)	//Spring 4.2 利用@Order控制配置类的加载顺序
public class AnnotationImplement 
	//切面
	@Pointcut("@annotation(com.ymhj.yas.yoshinoya.aop.MyAnnotation)")
	public void annotation()
		//此处什么都不用写
	
	
	//此处写具体的实现
	//定义通知(前置)
	//切面类(依然放在com.abc.advice包中)中定义了Before、Around、AfterReturning和After 4中增强处理
	//ProceedingJoinPoint :使用这个类取处理日志,只能处理环绕通知,该类是JoinPoint的子类:ProceedingJoinPoint is only supported for around advice
	@Before("annotation()")
	public void beforePoint(JoinPoint point)
		
		/**********************注解处理器**************/
		System.err.println(point.getTarget().getClass().getName());//获取目标对象对应的类名
		//获取实现类继承的接口名
	    @SuppressWarnings("rawtypes")
	    Class[] c = point.getTarget().getClass().getInterfaces();
	    System.err.println("实现类继承的接口名:"+c[0]);
	    
	  //获取在这个service实现类上的annotation
	   Annotation[] a = point.getTarget().getClass().getAnnotations();
	 //获取这个类上的注解的个数
       System.out.println("应用注解类上的注解个数:"+a.length);
       //判断这个类上面的注释是否是AnnotationName这个自定义的注解,如果是返回这个注解,如果不是返回null
       if(point.getTarget().getClass().getAnnotation(MyAnnotation.class)!=null)
           //获取到这个类上的注解
    	   MyAnnotation anns = point.getTarget().getClass().getAnnotation(MyAnnotation.class);
            //输出这个类上的注解的值
           System.out.println("注释在实现类上的annotation:"+anns.descraption());
       
       //判断这个接口上是否存在此注解
       if(c[0].getAnnotation(MyAnnotation.class)!=null)
    	   MyAnnotation an = (MyAnnotation) c[0].getAnnotation(MyAnnotation.class);
           System.out.println("注解对象所实现接口上的注解值:"+an.descraption());
       
       //获取目标对象上正在执行的方法名
		System.err.println("目标对象上正在执行的方法名:"+point.getSignature().getName());//方法名
		 //获取到这个类上面的所有方法全名
	       Method meths[] = point.getSignature().getDeclaringType().getMethods();
	       System.out.println("方法上面的全名:"+meths[0]);
	       //获取到这个类上面的方法上面的注解
	       Annotation[] anns = meths[1].getDeclaredAnnotations();
	       System.out.println("正在执行方法上面的注解:"+((MyAnnotation)anns[2]).descraption());
	       //让你注释的那个方法执行
	       //point.proceed();
		
		
		/**********************注解处理器**************/
		
		Object[] objects=point.getArgs();//参数名
		for (int i = 0; i < objects.length; i++) 
			System.err.println(objects.toString());
		
	


    上面的demo中,声明的是一个运行时方法注解,所以在使用的时候,可以将@MyAnnotation注解放到某个方法上。



以上是关于Java自定义注解的主要内容,如果未能解决你的问题,请参考以下文章

JAVA里自定义注解来进行数据验证

Java自定义注解的使用

如何在java web项目中添加自定义注解

java里的自定义注解类型 有啥用?

java 自定义的注解有啥作用

Java自定义注解