Использование прокси в Spring AOP - PullRequest
21 голосов
/ 22 ноября 2011

Я читаю книгу, в которой говорится о включении поддержки AspectJ в Spring AOP.

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

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

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


Я не могу получить второй абзац.Что подразумевается под «, интерфейсы недоступны ».Кто-нибудь может проиллюстрировать это на примере?

Ответы [ 4 ]

27 голосов
/ 22 ноября 2011

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

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

Таким образом вы можете принудительно создать прокси-серверы CGLIB (set proxy-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 документация для более подробной информации.

20 голосов
/ 22 ноября 2011

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

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

public interface MyService {
    void doSomething();
}

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

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

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

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

6 голосов
/ 17 сентября 2013

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

Когда кодирование интерфейса не выполняется (цитата из раздела блога ' Что если класс бинов не реализует какой-либо интерфейс? '): -

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

5 голосов
/ 30 ноября 2012

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

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

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

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

...