Каков наилучший способ внедрить тот же экземпляр службы в сервис для Spring AOP

Я имею ServiceImpl с аннотированным @Service стереотипом Spring и имеет два метода, каждый из которых аннотирован пользовательскими аннотациями, которые перехватываются Spring.

@Service    
public class ServiceImpl implements Service{

       @CustomAnnotation
       public void method1(){
       ...
       }

       @AnotherCustomAnnotation
       public void method2(){
        this.method1();   
        ...
       }
    }
}

Теперь Spring использует AOP-подход, основанный на прокси this.method1() Перехватчик для @CustomAnnotation не сможет перехватить этот вызов. Мы использовали для внедрения этого сервиса в другой FactoryClass и таким образом мы смогли получить экземпляр прокси, как -

  @AnotherCustomAnnotation
    public void method2(){
        someFactory.getService().method1();   
        ...
    }

Я сейчас использую Spring 3.0.x, какой лучший способ получить экземпляр прокси?

3 ответа

Решение

Другой альтернативой является использование AspectJ и @Configurable. Кажется, весна приближается к этим дням (благосклонно).

Я бы посмотрел на это, если вы используете Spring 3, так как он быстрее (производительность) и более гибкий, чем на основе прокси.

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

  1. Измените свой дизайн (это то, что я бы порекомендовал)
  2. Изменить тип прокси с JDK-proxy на proxy-target-class (на основе подклассов CGLib) Нет, это не помогает, см. Комментарий @ axtavt, это должна быть статическая компиляция AspectJ.
  3. использование ((Service)AopContext.currentProxy()).method1() (Работает, но является ужасным нарушением AOP, см. Конец Понимания AOP-прокси)

Вы можете заставить свой класс ServiceImpl реализовывать интерфейс BeanFactoryAware и выполнять поиск самостоятельно благодаря предоставленной фабрике бинов. Но это больше не инъекция зависимости.

Лучшее решение - поместить method1 в другой компонент службы, который будет внедрен в существующий компонент службы и которому делегирует ваш существующий компонент службы.

Другие вопросы по тегам