Kehilangan Anotasi Kustom Kelas Untuk Kelas Proxy

Saya menggunakan Seam untuk menyuntikkan kacang ke pengontrol saya menggunakan anotasi @In. Kelas yang disuntikkan memiliki anotasi khusus, saat memanggil injectionClass.getClass().getAnnotation(annotationClass) ia mengembalikan null.

Saat debug, saya menemukan bahwa Seam meneruskan instance proxy sehingga getClass() mengembalikan InjectedClass_$$_javassist_seam_5 yang tidak memiliki anotasi khusus saya.

Bagaimana saya bisa mendapatkan anotasi khusus dari kelas proxy?

Berikut tampilan kelas saya:

@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 sumber
comment
Akan sangat membantu jika Anda dapat memposting bagian yang relevan dari kode sumber kelas yang Anda masukkan.   -  person skaffman    schedule 30.12.2009
comment
Saya memodifikasi deskripsi pertanyaan untuk mendapatkan contoh kode   -  person Noura    schedule 30.12.2009
comment
@Noura Ditambahkan ke jawaban asli   -  person Arthur Ronald    schedule 30.12.2009


Jawaban (2)


Pertanyaan bagus.

Saat Anda memanggil metode menggunakan Seam, metode tersebut disadap oleh proxy. Dan yang ini mengaktifkan @In atau @Out-jection. Namun ada pengecualian untuk aturan ini: aturan ini tidak berfungsi saat Anda memanggil metode internal

Jadi coba kode ini

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

}

Ditambahkan ke jawaban asli

Anda ingin mengambil anotasi dari kacang Anda. Namun, karena metode pencegat, myAnnotatedClass.getClass() mengembalikan objek proxy, bukan kelas kacang itu sendiri.

Untuk setiap kelas kacang, Seam membuat definisi Komponen, yang disimpan dalam konteks aplikasi. Nama atribut mengikuti pola berikut: nama komponen ditambah .component. Jadi jika Anda punya kacang seperti ini

@Name("myBean")
public class MyBean {

}

Definisi Komponennya disimpan dalam atribut myBean.component

Jadi di dalam metode Anda, Anda dapat menggunakannya

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

Sekarang Anda dapat menelepon

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

salam,

person Arthur Ronald    schedule 30.12.2009
comment
Terima kasih atas balasan Anda, tetapi tidak berhasil. Saya menggunakan pembungkus untuk MyAnnotatedClass, pembungkus tersebut memiliki anotasi @Name, bukan MyAnnotatedClass. Sekarang pengontrol telah menyuntikkan pembungkusnya dan memanggil wrapper.getMyAnnotatedClass().getAnnotation(annotationClass) Saya pikir ini adalah solusi yang buruk, tetapi ini memperbaiki masalah sampai kita memiliki solusi yang lebih baik. - person Noura; 30.12.2009
comment
ya, itu mendapat penjelasannya. Saya juga bisa mendapatkan anotasi menggunakan myAnnotatedClass.getSuperClass().getAnnotation(CustomAnnotation.class), Tapi saya tidak bisa mendapatkan bidang dengan refleksi. Saya mengulangi myAnnotatedClass.getSuperClass().getClass().getDeclaredFields(). Kemudian panggil field.get(myAnnotatedClass), ketika meneruskan objek proxy, ia mengeluarkan pengecualian. - person Noura; 30.12.2009

Jika Anda ingin mengurangi kelebihan "ComponentDefinition", Anda juga bisa menggunakan ini yang juga berfungsi untuk CDI dan Spring:

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