ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

【Java】关于获取注解的问题发现

2021-10-26 21:34:59  阅读:130  来源: 互联网

标签:Files Java Repository jar Maven 获取 Program 注解 Local


同事设置了个注解,想用Spring获取的Bean来找到Class获取注解

但是发现是空的,在查看的Spring返回Bean之后,发现这个Bean对象并不是原生的实例

而是被Spring代理增强的代理对象

 

为了复现这个问题,这里我写了个样例:

首先有两个样例注解(一个叫A 一个叫B,B也是一样的就不写了):

package cn.cloud9.test.reflect.annotation;

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

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoA {
    String value() default "";
}

再写一个A类,里面就是一个方法没别的

打上A和B注解

package cn.cloud9.test.reflect.sample;

import cn.cloud9.test.reflect.annotation.AnnoA;
import cn.cloud9.test.reflect.annotation.AnnoB;

@AnnoA
@AnnoB
public class A {

    public void fun() {
        System.out.println("A.fun executed... ");
    }
}

 

为了模拟Spring代理的场景,这里要引入CGLIB组件

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

 

编写样例代码:

package cn.cloud9.test.reflect;

import cn.cloud9.test.reflect.sample.A;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

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

public class ReflectAndAnnotation {


    @Test
    public void simpleGet() throws Exception {

        Class<?> aClass = Class.forName("cn.cloud9.test.reflect.sample.A");

        Annotation[] annotations = aClass.getAnnotations();

        Class<?> superclass = aClass.getSuperclass();
        System.out.println(superclass);

        for (Annotation annotation : annotations) {
            System.out.println(annotation.toString());
        }
    }

}

执行之后,自然而然的就能得到我们设置的注解:

"C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar=57548:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;C:\Users\Cloud9\IdeaProjects\EveryThing-Framework\target\test-classes;C:\Users\Cloud9\IdeaProjects\EveryThing-Framework\target\classes;D:\Maven Local Repository\org\apache\curator\curator-framework\5.2.0\curator-framework-5.2.0.jar;D:\Maven Local Repository\org\apache\curator\curator-client\5.2.0\curator-client-5.2.0.jar;D:\Maven Local Repository\org\apache\zookeeper\zookeeper\3.6.3\zookeeper-3.6.3.jar;D:\Maven Local Repository\org\apache\zookeeper\zookeeper-jute\3.6.3\zookeeper-jute-3.6.3.jar;D:\Maven Local Repository\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;D:\Maven Local Repository\io\netty\netty-handler\4.1.63.Final\netty-handler-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-common\4.1.63.Final\netty-common-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-resolver\4.1.63.Final\netty-resolver-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-buffer\4.1.63.Final\netty-buffer-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport\4.1.63.Final\netty-transport-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-codec\4.1.63.Final\netty-codec-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport-native-epoll\4.1.63.Final\netty-transport-native-epoll-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport-native-unix-common\4.1.63.Final\netty-transport-native-unix-common-4.1.63.Final.jar;D:\Maven Local Repository\org\apache\curator\curator-recipes\5.2.0\curator-recipes-5.2.0.jar;D:\Maven Local Repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;D:\Maven Local Repository\commons-beanutils\commons-beanutils\1.7.0\commons-beanutils-1.7.0.jar;D:\Maven Local Repository\commons-logging\commons-logging\1.0.3\commons-logging-1.0.3.jar;D:\Maven Local Repository\org\javassist\javassist\3.26.0-GA\javassist-3.26.0-GA.jar;D:\Maven Local Repository\com\alibaba\fastjson\1.2.78\fastjson-1.2.78.jar;D:\Maven Local Repository\javax\servlet\javax.servlet-api\4.0.1\javax.servlet-api-4.0.1.jar;D:\Maven Local Repository\javax\servlet\jstl\1.2\jstl-1.2.jar;D:\Maven Local Repository\javax\servlet\jsp\javax.servlet.jsp-api\2.3.3\javax.servlet.jsp-api-2.3.3.jar;D:\Maven Local Repository\org\reflections\reflections\0.9.11\reflections-0.9.11.jar;D:\Maven Local Repository\com\google\guava\guava\20.0\guava-20.0.jar;D:\Maven Local Repository\mysql\mysql-connector-java\8.0.25\mysql-connector-java-8.0.25.jar;D:\Maven Local Repository\com\google\protobuf\protobuf-java\3.11.4\protobuf-java-3.11.4.jar;D:\Maven Local Repository\io\jsonwebtoken\jjwt\0.9.1\jjwt-0.9.1.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-databind\2.9.6\jackson-databind-2.9.6.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-core\2.9.6\jackson-core-2.9.6.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpclient\4.5.13\httpclient-4.5.13.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpcore\4.4.13\httpcore-4.4.13.jar;D:\Maven Local Repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpmime\4.5.13\httpmime-4.5.13.jar;D:\Maven Local Repository\junit\junit\4.12\junit-4.12.jar;D:\Maven Local Repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\Maven Local Repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\Maven Local Repository\org\slf4j\slf4j-log4j12\1.7.32\slf4j-log4j12-1.7.32.jar;D:\Maven Local Repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\Maven Local Repository\cglib\cglib\2.2.2\cglib-2.2.2.jar;D:\Maven Local Repository\asm\asm\3.3.1\asm-3.3.1.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 cn.cloud9.test.reflect.ReflectAndAnnotation,simpleGet
class java.lang.Object
@cn.cloud9.test.reflect.annotation.AnnoA(value=)
@cn.cloud9.test.reflect.annotation.AnnoB(value=)

Process finished with exit code 0

 

那么在调用CGLIB的增强代理之后:

package cn.cloud9.test.reflect;

import cn.cloud9.test.reflect.sample.A;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

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

public class ReflectAndAnnotation {


    @Test
    public void simpleGet() throws Exception {

        Class<?> aClass = Class.forName("cn.cloud9.test.reflect.sample.A");

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(aClass);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("before method run...");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("after method run...");
                return result;
            }
        });
        A proxyA = (A) enhancer.create();
        proxyA.fun();

        Class<? extends A> proxyAClass = proxyA.getClass();

        System.out.println(proxyAClass);

        for (Annotation annotation : proxyAClass.getAnnotations()) {
            System.out.println(annotation);
        }

    }

}

执行发现,我们注解获取不到了

"C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar=57581:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit5-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;C:\Users\Cloud9\IdeaProjects\EveryThing-Framework\target\test-classes;C:\Users\Cloud9\IdeaProjects\EveryThing-Framework\target\classes;D:\Maven Local Repository\org\apache\curator\curator-framework\5.2.0\curator-framework-5.2.0.jar;D:\Maven Local Repository\org\apache\curator\curator-client\5.2.0\curator-client-5.2.0.jar;D:\Maven Local Repository\org\apache\zookeeper\zookeeper\3.6.3\zookeeper-3.6.3.jar;D:\Maven Local Repository\org\apache\zookeeper\zookeeper-jute\3.6.3\zookeeper-jute-3.6.3.jar;D:\Maven Local Repository\org\apache\yetus\audience-annotations\0.5.0\audience-annotations-0.5.0.jar;D:\Maven Local Repository\io\netty\netty-handler\4.1.63.Final\netty-handler-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-common\4.1.63.Final\netty-common-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-resolver\4.1.63.Final\netty-resolver-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-buffer\4.1.63.Final\netty-buffer-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport\4.1.63.Final\netty-transport-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-codec\4.1.63.Final\netty-codec-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport-native-epoll\4.1.63.Final\netty-transport-native-epoll-4.1.63.Final.jar;D:\Maven Local Repository\io\netty\netty-transport-native-unix-common\4.1.63.Final\netty-transport-native-unix-common-4.1.63.Final.jar;D:\Maven Local Repository\org\apache\curator\curator-recipes\5.2.0\curator-recipes-5.2.0.jar;D:\Maven Local Repository\commons-io\commons-io\2.11.0\commons-io-2.11.0.jar;D:\Maven Local Repository\commons-beanutils\commons-beanutils\1.7.0\commons-beanutils-1.7.0.jar;D:\Maven Local Repository\commons-logging\commons-logging\1.0.3\commons-logging-1.0.3.jar;D:\Maven Local Repository\org\javassist\javassist\3.26.0-GA\javassist-3.26.0-GA.jar;D:\Maven Local Repository\com\alibaba\fastjson\1.2.78\fastjson-1.2.78.jar;D:\Maven Local Repository\javax\servlet\javax.servlet-api\4.0.1\javax.servlet-api-4.0.1.jar;D:\Maven Local Repository\javax\servlet\jstl\1.2\jstl-1.2.jar;D:\Maven Local Repository\javax\servlet\jsp\javax.servlet.jsp-api\2.3.3\javax.servlet.jsp-api-2.3.3.jar;D:\Maven Local Repository\org\reflections\reflections\0.9.11\reflections-0.9.11.jar;D:\Maven Local Repository\com\google\guava\guava\20.0\guava-20.0.jar;D:\Maven Local Repository\mysql\mysql-connector-java\8.0.25\mysql-connector-java-8.0.25.jar;D:\Maven Local Repository\com\google\protobuf\protobuf-java\3.11.4\protobuf-java-3.11.4.jar;D:\Maven Local Repository\io\jsonwebtoken\jjwt\0.9.1\jjwt-0.9.1.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-databind\2.9.6\jackson-databind-2.9.6.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\Maven Local Repository\com\fasterxml\jackson\core\jackson-core\2.9.6\jackson-core-2.9.6.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpclient\4.5.13\httpclient-4.5.13.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpcore\4.4.13\httpcore-4.4.13.jar;D:\Maven Local Repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;D:\Maven Local Repository\org\apache\httpcomponents\httpmime\4.5.13\httpmime-4.5.13.jar;D:\Maven Local Repository\junit\junit\4.12\junit-4.12.jar;D:\Maven Local Repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\Maven Local Repository\org\slf4j\slf4j-api\1.7.32\slf4j-api-1.7.32.jar;D:\Maven Local Repository\org\slf4j\slf4j-log4j12\1.7.32\slf4j-log4j12-1.7.32.jar;D:\Maven Local Repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\Maven Local Repository\cglib\cglib\2.2.2\cglib-2.2.2.jar;D:\Maven Local Repository\asm\asm\3.3.1\asm-3.3.1.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 cn.cloud9.test.reflect.ReflectAndAnnotation,simpleGet
before method run...
A.fun executed... 
after method run...
class cn.cloud9.test.reflect.sample.A$$EnhancerByCGLIB$$fe34985a

Process finished with exit code 0

 

为什么获取不到?

因为 这个是代理的对象,那么代理对象也应该由一个类来创建

这个类是代理对象类  class cn.cloud9.test.reflect.sample.A$$EnhancerByCGLIB$$fe34985a ,那么代理对象类会有我们设置的注解吗?

结果是没有的,但是根据CGLIB代理的实现原理,CGLIB代理原理是通过继承实现的,所以我们是不是可以通过代理类向上找父类来获取?

 

下面就是对猜想的测试:

package cn.cloud9.test.reflect;

import cn.cloud9.test.reflect.sample.A;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.junit.Test;

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

public class ReflectAndAnnotation {


    @Test
    public void simpleGet() throws Exception {

        Class<?> aClass = Class.forName("cn.cloud9.test.reflect.sample.A");

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(aClass);
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                System.out.println("before method run...");
                Object result = proxy.invokeSuper(obj, args);
                System.out.println("after method run...");
                return result;
            }
        });
        A proxyA = (A) enhancer.create();
        proxyA.fun();

        Class<? extends A> proxyAClass = proxyA.getClass();

        System.out.println(proxyAClass);

        for (Annotation annotation : proxyAClass.getAnnotations()) {
            System.out.println(annotation);
        }
        
        // 获取父类
        Class<?> superclass1 = proxyAClass.getSuperclass();
        System.out.println(superclass1);
        for (Annotation annotation : superclass1.getAnnotations()) {
            System.out.println(annotation);
        }
    }
}

执行结果发现,代理对象的父类就是我们原来的类

从原类再次获取注解,结果是可以的

before method run...
A.fun executed... 
after method run...
class cn.cloud9.test.reflect.sample.A$$EnhancerByCGLIB$$fe34985a
class cn.cloud9.test.reflect.sample.A
@cn.cloud9.test.reflect.annotation.AnnoA(value=)
@cn.cloud9.test.reflect.annotation.AnnoB(value=)

 

 

由此可以推断JDK的接口实现代理的方式

对象要增强就需要通过接口实现处理,也就是说实际的接口对象,是实现类的对象

 

注解在接口上,要通过实现类找到对应的接口,通过接口实例,再找到标注的注解

注解在实现类上,就可以直接通过实现类,获取标注的注解

 

标签:Files,Java,Repository,jar,Maven,获取,Program,注解,Local
来源: https://www.cnblogs.com/mindzone/p/15467932.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有