Внутренние элементы Spring Framework и других контейнеров IoC

Я использую spring в течение некоторого времени, но я всегда задавался вопросом, как это работает, точнее, как они загружают и переплетают beans/классы, помеченные только интерфейсом или @annotation.

Для объявлений xml легко видеть, как spring выполняет предварительную обработку моего beans (они объявлены в контексте xml, который читает spring), но для классов, отмеченных только аннотациями, я не вижу как это работает, так как я не передаю какой-либо агент в jvm или около того.

Я считаю, что есть некоторый крючок Java/JVM, который позволяет вам обрабатывать классы по каким-то критериям, но я не смог ничего узнать в документах.

Может кто-нибудь указать мне на некоторые документы? Связано ли это с API java.lang.instrument.ClassFileTransformer?

Ответы

Ответ 1

Фактически по умолчанию Spring не работает выполнять любую постобработку по байткоду ни для XML-, ни для построенный с аннотацией beans. Вместо релевантные beans завернуты в динамические прокси (см. java.lang.reflect.Proxy в Java SDK). Динамические прокси-серверы фактические объекты, которые вы используете и перехватываете вызовы методов, позволяющие применять АОП советы. Разница заключается в том, что прокси-серверы представляют собой, по существу, новые искусственные классы, созданные каркасом, тогда как постобработка ткачества/байткода изменяет существующие. Последнее невозможно без использования API-интерфейса Instrumentation, о котором вы говорили.

Что касается аннотаций, реализация тега <context:component-scan> сканирует путь к классам для всех классов с помощью аннотаций Spring и создает для них теги метаданных Spring. После этого они обрабатываются так, как если бы они были настроены с помощью XML (или, более конкретно, оба они обрабатываются одинаково).

Хотя Spring не выполняет постобработку по байт-коду, вы можете настроить агент ткачества AspectJ, который должен отлично работать с Spring, если прокси не удовлетворяют вас.