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

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

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

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

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

Заключение в кавычки процитированного вопроса:

public SomeClass {
  @Inject
  private SomeResource resource;
}

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

Спасибо

11
задан Community 23 May 2017 в 12:13
поделиться

3 ответа

Это простой "трюк" с отражением. Он полагается на метод Field.setAccessible () для обеспечения программного доступа к члену:

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

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

См. Пример здесь .

Никакой магии, никакой кастомной ВМ.

16
ответ дан 3 December 2019 в 04:13
поделиться

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

3
ответ дан 3 December 2019 в 04:13
поделиться

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

//......................................................
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
6
ответ дан 3 December 2019 в 04:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: