Подтвердить что ты не робот

Использование прокси в Spring АОП

Я читаю книгу, в которой говорится о возможности поддержки AspectJ в Spring АОП.

Ниже приведен абзац из книги:

Чтобы включить поддержку аннотаций AspectJ в контейнере IoC Spring, вам нужно определить пустой XML-элемент aop: aspectj-autoproxy в конфигурационном файле bean. Затем Spring будет автоматически создайте прокси для любого из ваших beans, которые соответствуют вашим аспектам AspectJ.

В случаях, когда интерфейсы недоступны или не используются в дизайне приложений, возможно создавать прокси, полагаясь на CGLIB. Чтобы включить CGLIB, вам необходимо установить атрибут proxy-targetclass= true в aop: aspectj-autoproxy.


Я не могу получить второй абзац. Что означает "интерфейсы недоступны". Может ли кто-нибудь проиллюстрировать это с помощью примера?

4b9b3361

Ответ 1

Spring AOP использует динамические прокси JDK или CGLIB для создания прокси-серверов для ваших целевых объектов.

Согласно документации Spring, если ваша цель реализует хотя бы один интерфейс, будет использоваться динамический прокси JDK. Однако, если ваш целевой объект не реализует никаких интерфейсов, тогда будет создан прокси CGLIB.

Вот как вы можете принудительно создать прокси CGLIB (установить прокси-target- class= " true" ):

 <aop:config proxy-target-class="true">
    <!-- other beans defined here... -->
 </aop:config>

При использовании AspectJ и его поддержки autopoxy вы также можете заставить прокси CGLIB. Здесь используется <aop:aspectj-autoproxy>, а также здесь для параметра "proxy-target-class" должно быть установлено значение true:

<aop:aspectj-autoproxy proxy-target-class="true"/>

Подробнее см. раздел "Механизмы проксирования" Аспектно-ориентированное программирование с Spring.

Ответ 2

Spring предпочитает использовать интерфейсы для АОП, поскольку он может использовать JDK прокси.

Скажем, например, у меня есть интерфейс MyService

public interface MyService {
    void doSomething();
}

И реализация MyServiceImpl

@Service
public class MyServiceImpl implements MyService {
    public void doSomething() {
        // does something!
    }
}

Если Spring обнаруживает, что вы настроили аспекты для MyService, он создаст прокси-сервер JDK, который реализует MyService, а затем проксирует все вызовы на ваш MyServiceImpl bean, добавив функции аспекта, где это необходимо.

Прокси-серверы JDK работают, реализуя тот же интерфейс, что и ваш целевой объект, и делегируя ему вызовы; они не работают, если нет интерфейса для реализации. Если у вас нет интерфейса, такого как выше, Spring необходимо использовать библиотеку байтового кода, такую ​​как CGLIB, для динамического создания классов во время выполнения, которые включают функциональность аспект.

Ответ 3

Spring AOP широко использует прокси-серверы в качестве механизма для реализации сквозных проблем (ака-аспектов) неинтрузивным способом, идея в основном заключается в использовании прокси-серверов в качестве оболочек, которые обогащают исходное поведение, то есть добавляют транзакционные возможности.

Для этого есть два варианта, в зависимости от того, реализует ли исходный объект интерфейс или нет.

В первом случае (исходный объект реализует хотя бы один интерфейс) возможности динамического прокси-интерфейса API отражения используются для создания прокси-объекта, который ИСПОЛЬЗУЕТ те же интерфейсы, что и исходный объект, и поэтому вместо этого можно использовать прокси.

Во втором случае (исходный объект НЕ реализует какой-либо интерфейс), поэтому необходимо использовать более сложный трюк, и это происходит, когда появляется CGLIB. Согласно странице проекта "CGLIB используется для расширения классов Java и реализации интерфейсов во время выполнения". Таким образом, в этом случае трюк состоит в создании прокси, который EXTENDS исходного объекта и, следовательно, может быть использован вместо него.

Ответ 4

Я нашел блог здесь, в котором четко объясняется, как работают AOP, Caching и Transaction с использованием прокси-классов runtime.

Если не кодирование для интерфейса (цитирование из раздела блога Что делать, если класс bean не реализует какой-либо интерфейс? '): -

По умолчанию, если ваш bean не реализует интерфейс, Spring использует техническое наследование: во время запуска создается новый класс. Это наследует от вашего класса bean и добавляет поведение в дочерние методы. Чтобы создать такие прокси, Spring использует стороннюю библиотеку cglib.