การสูญเสียคำอธิบายประกอบแบบกำหนดเองของคลาสสำหรับคลาสพร็อกซี

ฉันกำลังใช้ Seam เพื่อฉีดถั่วให้กับคอนโทรลเลอร์ของฉันโดยใช้ @In คำอธิบายประกอบ คลาสที่ฉีดมีคำอธิบายประกอบที่กำหนดเอง เมื่อเรียก injectedClass.getClass().getAnnotation(annotationClass) ก็จะส่งคืนค่าว่าง

เมื่อทำการดีบัก ฉันพบว่า Seam ส่งผ่านอินสแตนซ์พร็อกซี ดังนั้น getClass() จึงส่งคืน InjectedClass_$$_javassist_seam_5 ซึ่งไม่มีคำอธิบายประกอบที่กำหนดเองของฉัน

ฉันจะรับคำอธิบายประกอบที่กำหนดเองจากคลาสพร็อกซีได้อย่างไร

ชั้นเรียนของฉันมีลักษณะดังนี้:

@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 
     }
}

person Noura    schedule 30.12.2009    source แหล่งที่มา
comment
มันจะช่วยได้มากหากคุณสามารถโพสต์ส่วนที่เกี่ยวข้องของซอร์สโค้ดของคลาสที่ฉีดเข้าไปได้   -  person skaffman    schedule 30.12.2009
comment
ฉันแก้ไขคำอธิบายคำถามให้มีตัวอย่างโค้ด   -  person Noura    schedule 30.12.2009
comment
@Noura เพิ่มไปยังคำตอบเดิม   -  person Arthur Ronald    schedule 30.12.2009


คำตอบ (2)


คำถามที่ดี.

เมื่อคุณเรียกเมธอดโดยใช้ Seam นั้นจะถูกดักโดยพรอกซี และอันนี้เปิดใช้งาน @In หรือ @Out-jection แต่มีข้อยกเว้นสำหรับกฎนี้: มันไม่ทำงานเมื่อคุณเรียกใช้เมธอดภายใน

เลยลองโค้ดนี้ดู

@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));
    }

}

เพิ่มไปยังคำตอบเดิม

คุณต้องการดึงคำอธิบายประกอบจาก bean ของคุณ แต่เนื่องจากตัวสกัดกั้นเมธอด myAnnotatedClass.getClass() จึงส่งคืนอ็อบเจ็กต์พร็อกซี ไม่ใช่คลาส bean เอง

สำหรับแต่ละคลาส bean นั้น Seam จะสร้างคำจำกัดความของ Component ซึ่งถูกจัดเก็บไว้ในบริบทของแอปพลิเคชัน ชื่อของแอตทริบิวต์เป็นไปตามรูปแบบนี้: ชื่อส่วนประกอบ บวก .component ดังนั้นถ้าคุณมีถั่วแบบนี้

@Name("myBean")
public class MyBean {

}

คำจำกัดความของ Componet ถูกจัดเก็บไว้ในแอตทริบิวต์ myBean.component

ดังนั้นภายในวิธีการของคุณ คุณสามารถใช้ได้

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

ตอนนี้คุณสามารถโทร

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

ความนับถือ,

person Arthur Ronald    schedule 30.12.2009
comment
ขอบคุณสำหรับคำตอบของคุณ แต่มันไม่ทำงาน ฉันใช้ wrapper สำหรับ MyAnnotatedClass wrapper มีคำอธิบายประกอบ @Name แทนที่จะเป็น MyAnnotatedClass ตอนนี้คอนโทรลเลอร์ได้ฉีด wrapper เข้าไปแล้ว และมันเรียก wrapper.getMyAnnotatedClass().getAnnotation(annotationClass) ฉันคิดว่ามันเป็นวิธีแก้ปัญหาที่น่าเกลียด แต่มันแก้ไขปัญหาได้จนกว่าเราจะมีวิธีที่ดีกว่า - person Noura; 30.12.2009
comment
ใช่ นั่นได้รับคำอธิบายประกอบ ฉันยังสามารถรับคำอธิบายประกอบโดยใช้ myAnnotatedClass.getSuperClass().getAnnotation(CustomAnnotation.class) แต่ฉันไม่สามารถรับฟิลด์จากการสะท้อนกลับได้ ฉันทำซ้ำใน myAnnotatedClass.getSuperClass().getClass().getDeclaredFields() จากนั้นโทรไปที่ field.get(myAnnotatedClass) เมื่อส่งผ่านวัตถุพร็อกซี มันจะส่งข้อยกเว้น - person Noura; 30.12.2009

หากคุณต้องการโอเวอร์โหลด "ComponentDefinition" น้อยลง คุณสามารถใช้สิ่งนี้ซึ่งใช้ได้กับ CDI และ Spring ด้วย:

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