Как серверы приложений внедряются в частные поля?



Я видел этот вопрос



Впрыснуть в частное, пакетное или публичное поле или предоставить сеттер?



О том, как вручную вводить в аннотированные частные поля (способ добавления сеттеров
или через конструктор)



Но, дело в том, как сделать сервер приложений (как glassfish, axis2, jboss, ...)
способен вводить в конечное частное поле (без добавления сеттеров или конструкторов
к пользовательскому классу)?



Цитируя процитированный вопрос:



public SomeClass {
@Inject
private SomeResource resource;
}


Do они используют настроенный JVM (не стандартный), который позволяет получить доступ к частным полям?



Спасибо

598   3  

3 ответов:

Это простая рефлексия "трюк". Он полагается на Field.setAccessible() метод принудительного доступа к элементу программно:

Установите для этого флаг доступный объект к указанному логическому значению. Значение true указывает на то, что отраженный объект должен подавлять Java проверка доступа к языку, когда он есть использованный. Значение false указывает на то, что отражаемого объекта следует обеспечивать Проверка доступа к языку Java.

Используется API отражения чтобы получить дескриптор на поле, вызывается setAccessible(), а затем он может быть задан рамкой инъекции.

Смотрите пример здесь.

Нет магии, нет пользовательской виртуальной машины.

С помощью скаффмана я закодировал этот простой пример о том, как вводить без сеттеров. Возможно, это помогает (это было со мной)

//......................................................
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

Выполнить вывод:

------- fields : --------
 -> private int MyClass.theValue
       found annotation: @Inject()
       injecting !
23

Также стоит отметить, что некоторые фреймворки используют проектирование байт-кода через пользовательский загрузчик классов для достижения того же результата без затрат на отражение (отражение может быть довольно дорогим в разы)

Comments

    Ничего не найдено.