创建自定义注解
*/
@Target({ ElementType.METHOD, ElementType.TYPE })br/>@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation {
String value();
}
通过反射获取注解
public class Test {
@TestAnnotation(value = "测试方法")
public static void main(String args[]){
try {
Class c=Test.class;
Method[] methods=c.getDeclaredMethods();
for(Method method:methods){
Annotation[] annotations=method.getDeclaredAnnotations();
for(Annotation annotation:annotations){
TestAnnotation testAnnotation= (TestAnnotation) annotation;
System.out.println(testAnnotation.value());
}
}
} catch (ClassNotFoundException e) {br/>e.printStackTrace();
}
}
}
四、web开发中的运用
在web开发中,权限控制非常重要,所以有些接口会限制必须登录之后才能访问,但是个别接口并没有这种限制。一种方式是把需要过滤的ThinkMarkets代理申请www.kaifx.cn/broker/thinkmarkets.html接口或者方法配置在文件中,每次请求时在拦截器中根据请求的路径与配置文件中的对比过滤。其实还有另外一种方式就是通过注解方式。
定义一个注解NoLogin
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)br/>@Documented
public @interface NoLogin {
}
标注在方法上
在拦截器中判断方法上是否有NoLogin注解
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
//支持两种方式过滤 1、注解方式 添加@NoLogin注解
HandlerMethod handlerMethod= (HandlerMethod) o;
NoLogin noLogin=handlerMethod.getMethod().getDeclaredAnnotation(NoLogin.class);
if(null!=noLogin){
return true;
}
}
五、java内置的注解
除了上述的四个元注解,java还内置了另外三个注解:
@Override 它没有任何的属性,不能存储任何其他信息。它只能作用于方法之上,编译结束后将被丢弃。在java编译器编译成字节码的时候,一旦发现某个方法被这个注解标识过,就会匹配父类中是否存在同一方法,如果不存在就回编译失败。br/>@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Deprecated 弃用的注解br/>@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
@SuppressWarnings 压制警告,比如某段代码中存在过时的方法,那么在编译过程中,会有warn警告,如果不想出现类似的警告,可在方法上添加这个注解。这个注解有一个value的值,这个value表示需要压制的警告类型。
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})br/>@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
/**
- The set of warnings that are to be suppressed by the compiler in the
- annotated element. Duplicate names are permitted. The second and
- successive occurrences of a name are ignored. The presence of
- unrecognized warning names is <i>not</i> an error: Compilers must
- ignore any warning names they do not recognize. They are, however,
- free to emit a warning if an annotation contains an unrecognized
- warning name.
-
- <p> The string {@code "unchecked"} is used to suppress
- unchecked warnings. Compiler vendors should document the
- additional warning names they support in conjunction with this
- annotation type. They are encouraged to cooperate to ensure
- that the same names work across multiple compilers.
- @return the set of warnings to be suppressed*/String[] value();}六、注解的原理1、java.lang.annotation.Annotation中有这么一句话:The common interface extended by all annotation types 所有的注解都继承于这个接口。怎么理解呢?其实刚才上面例子中的注解可以理解为:public @interface TestAnnotation extends Annotation{}注解的本质就是一个继承了 Annotation 接口的接口为了方便理解和掌握注解,还是以刚才的TestAnnotation注解为例。在idea中配置启动参数,方便查看代理产生的类,参数如下:Dsun.misc.ProxyGenerator.saveGeneratedFiles=truemain方法运行结束后,会在/com/sun/proxy目录下生成一个代理类,反编译之后是这样的:代理类proxy1重写了TestAnnotation的所有方法,包括value()和从Annotation继承来的equals()、hashCode()等方法。package com.sun.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.lang.reflect.UndeclaredThrowableException;import org.fy.annotation.TestAnnotation;public final class $Proxy1 extends Proxy implements TestAnnotation {private static Method m1;private static Method m2;private static Method m4;private static Method m0;private static Method m3;public $Proxy1(InvocationHandler var1) throws {super(var1);}public final boolean equals(Object var1) throws {try {return (Boolean)super.h.invoke(this, m1, new Object[]{var1});} catch (RuntimeException | Error var3) {throw var3;} catch (Throwable var4) {throw new UndeclaredThrowableException(var4);}}public final String toString() throws {try {return (String)super.h.invoke(this, m2, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final Class annotationType() throws {try {return (Class)super.h.invoke(this, m4, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final int hashCode() throws {try {return (Integer)super.h.invoke(this, m0, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}public final String value() throws {try {return (String)super.h.invoke(this, m3, (Object[])null);} catch (RuntimeException | Error var2) {throw var2;} catch (Throwable var3) {throw new UndeclaredThrowableException(var3);}}static {try {m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));m2 = Class.forName("java.lang.Object").getMethod("toString");m4 = Class.forName("org.fy.annotation.TestAnnotation").getMethod("annotationType");m0 = Class.forName("java.lang.Object").getMethod("hashCode");m3 = Class.forName("org.fy.annotation.TestAnnotation").getMethod("value");} catch (NoSuchMethodException var2) {throw new NoSuchMethodError(var2.getMessage());} catch (ClassNotFoundException var3) {throw new NoClassDefFoundError(var3.getMessage());}}}在看proxy1构造函数中有一个接口InvocationHandler,这个接口的实例化对象又是谁?java中有一个专门用于注解类型的代理对象AnnotationInvocationHandler,位于sun.reflect.annotation包中。同样是invoke方法用于处理具体的业务。public Object invoke(Object var1, Method var2, Object[] var3) {String var4 = var2.getName();Class[] var5 = var2.getParameterTypes();if (var4.equals("equals") && var5.length == 1 && var5[0] == Object.class) {return this.equalsImpl(var3[0]);} else if (var5.length != 0) {throw new AssertionError("Too many parameters for an annotation method");} else {byte var7 = -1;switch(var4.hashCode()) {case -1776922004:if (var4.equals("toString")) {var7 = 0;}break;case 147696667:if (var4.equals("hashCode")) {var7 = 1;}break;case 1444986633:if (var4.equals("annotationType")) {var7 = 2;}}switch(var7) {case 0:return this.toStringImpl();case 1:return this.hashCodeImpl();case 2:return this.type;default:Object var6 = this.memberValues.get(var4);if (var6 == null) {throw new IncompleteAnnotationException(this.type, var4);} else if (var6 instanceof ExceptionProxy) {throw ((ExceptionProxy)var6).generateException();} else {if (var6.getClass().isArray() && Array.getLength(var6) != 0) {var6 = this.cloneArray(var6);}return var6;}}}}