Как Guice заполняет аннотированные поля - PullRequest
5 голосов
/ 05 марта 2012

Ради моего собственного образования я хотел создать простую платформу Dependency Injection, которая функционирует аналогично тому, как это делает Google Guice.Таким образом, когда класс загружается, он предварительно заполняет аннотированные поля данными из фабричного класса.

Я использую Reflections для сканирования всех своих фабричных классов во время компиляции и сохранения этих классов в статическом списке, чтобыкогда приходит время загружать мои классы, у меня есть ссылка на мои фабрики, чтобы я мог затем сканировать методы и возвращать соответствующие данные.

Где я застрял, как предварительно заполнить аннотированные поля моих классовфактически не делая никакой работы в реальном классе.Другими словами, когда класс загружен, мне нужно иметь возможность определить, помечены ли какие-либо поля конкретной аннотацией, и, если они есть, получить значение из класса фабрики.

Есть ликаким-то образом выполнить отражение класса прямо перед его загрузкой, предварительно заполнить определенные поля и затем вернуть экземпляр этого класса, который будет использоваться?

Я мог бы расширить все свои классы, которые требуют внедрения зависимостей, с помощьюбазовый класс, который выполняет всю эту работу, но я полагаю, что должен быть лучший способ, чтобы я мог просто использовать @Inject (или любую другую аннотацию, которую я решил использовать, чтобы сказать, что это поле требует DI) и «магически» всю работусделано.

1 Ответ

5 голосов
/ 05 марта 2012

Способ, которым Guice подходит к этому, заключается в том, что он будет заполнять только поля экземпляра , который сам был создан Guice 1 .Инжектор после создания экземпляра может использовать API Reflection для просмотра полей Class и проверки их аннотаций с помощью Field.getDeclaredAnnotations().

. Это также является причиной, по которой, когда вы хотите ввести в статическое поле, вам нужно использовать Binder.requestStaticInjection() для заполнения статических полей.

Guice не просто сканирует ваш код на наличие аннотаций;все инъекции происходят по явному запросу (например, requestStaticInjection(), Injector.getInstance() и т. д.).Теперь этот первоначальный явный запрос часто делается в некотором коде библиотеки.

Например, если вы используете guice-servlet, вы позволяете Guice создавать экземпляры вашего сервлета с помощью вызовов serve().with().Но если вы этого не сделали и вместо этого оставили конфигурацию сервлета в своем web.xml, Guice не будет внедрять его в ваш сервлет.

1 - Вы также можете запросить явное внедрение, используя Binder.requestInjection().

...