Losing Class Custom Annotation For Proxy Classes

喜你入骨 提交于 2021-01-27 12:47:55

问题


I am using Seam to inject beans to my controller using @In annotation. The injected class has a custom annotation, when calling injectedClass.getClass().getAnnotation(annotationClass) it returns null.

When debug I found that Seam passes a proxy instance so getClass() returns InjectedClass_$$_javassist_seam_5 which doesn't have my custom annotation.

How I can get my custom annotation from the proxy class?

Here's how my classes look like:

@CustomAnnotation(value="myvalue")
@Name("myAnnotatedClass")
public class MyAnnotatedClass extends SuperClass {...}

@Scope(ScopeType.SESSION)
@Name("myController")
public class MyController {
     @In("#{myAnnotatedClass}")
     private MyAnnotatedClass myAnnotatedClass;

     public void actionMethod(){
         //call another class which call myAnnotatedClass.getClass().getAnnotation(CustomAnnotation.class)
         //then do some reflection for MyAnnotatedClass fields 
     }
}

回答1:


Good question.

When you call a method by using Seam, it is intercepted by a proxy. And this one enables @In or @Out-jection. But There is an exception to this rule: it does not work when you call an internal method

So try this code

@Name
public class Service {

    @In
    private MyAnnotatedClass myAnnotatedClass;


    public void myInterceptedMethod() {
        // internal method bypass interceptor
        // So @In or @Out-jection is not enabled
        internalMethod();
    }

    private void internalMethod() {
        System.out.println(myAnnotatedClass.getClass().getAnnotation(annotationClass));
    }

}

Added to original answer

You want to retrieve an annotation from your bean. But, because of method interceptor, myAnnotatedClass.getClass() returns a proxy object, not the bean class itself.

For each bean class, Seam creates a Component definition, in which is stored in the application context. The name of the attribute follows this pattern: component name plus .component. So if you have a bean like this one

@Name("myBean")
public class MyBean {

}

Its Componet definition is stored in the attribute myBean.component

So inside your method, you can use

Component myBeanComponentDefinition = (Component) Context.getApplicationContext().get("myBean.component");

Now you can call

myBeanComponentDefinition.getBeanClass().getAnnotation(CustomAnnotation.class);

regards,




回答2:


If you want less "ComponentDefinition" overbloat, you could also use this which also works for CDI and Spring:

Class.forName(myBean.getClass().getCanonicalName().substring(0,myBean.getClass().getCanonicalName().indexOf("$"))).getAnnotation(MyAnnotation.class)


来源:https://stackoverflow.com/questions/1979717/losing-class-custom-annotation-for-proxy-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!