应用服务器如何注入私有字段?

cib*_*en1 11 java annotations dependency-injection

我看到了这个问题

注入私人,包装或公共领域或提供制定者?

关于如何手动注入带注释的私有字段(方式是添加setter或通过构造函数)

但是,重点是应用程序服务器(如glassfish,axis2,jboss,...)如何能够注入最终的私有字段(不向用户类添加setter或构造函数)?

引用引用的问题:

public SomeClass {
  @Inject
  private SomeResource resource;
}
Run Code Online (Sandbox Code Playgroud)

他们是否使用允许访问私有字段的自定义JVM(不是标准的JVM)?

谢谢

ska*_*man 16

这是一个简单的反思"技巧".它依赖于Field.setAccessible()强制以编程方式访问成员的方法:

将此对象的可访问标志设置为指示的布尔值.值true表示反射对象在使用时应禁止Java语言访问检查.值false表示反射对象应强制执行Java语言访问检查.

Reflection API用于获取字段上的句柄,setAccessible()被调用,然后它可以由注入框架设置.

在这里查看示例.

没有魔法,没有自定义VM.


cib*_*en1 6

在skaffman的帮助下,我编写了一个关于如何在没有setter的情况下进行注入的简单示例.也许它有帮助(它对我有用)

//......................................................
import java.lang.annotation.*;
import java.lang.reflect.*;

//......................................................
@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface Inject {
}

//......................................................
class MyClass {

    @Inject
    private int theValue = 0;

    public int getTheValue() {
        return theValue;
    }
} // class

//......................................................
public class Example {

    //......................................................
    private static void doTheInjection(MyClass u, int value) throws IllegalAccessException {

        Field[] camps = u.getClass().getDeclaredFields();

        System.out.println("------- fields : --------");
        for (Field f : camps) {
            System.out.println(" -> " + f.toString());
            Annotation an = f.getAnnotation(Inject.class);
            if (an != null) {
                System.out.println("       found annotation: " + an.toString());
                System.out.println("       injecting !");
                f.setAccessible(true);
                f.set(u, value);
                f.setAccessible(false);
            }
        }

    } // ()

    //......................................................
    public static void main(String[] args) throws Exception {

        MyClass u = new MyClass();

        doTheInjection(u, 23);

        System.out.println(u.getTheValue());

    } // main ()
} // class
Run Code Online (Sandbox Code Playgroud)

运行输出:

------- fields : --------
 -> private int MyClass.theValue
       found annotation: @Inject()
       injecting !
23
Run Code Online (Sandbox Code Playgroud)