2016-03-08 2 views
1

Я Следующий аспект класса:Spring AOP Аннотация не работает

@Component 
@Aspect 
public class LoggedRequestAspect { 

    private static final Logger LOG = LoggerFactory.getLogger(LoggedRequestAspect.class); 

    @Before("com.application.aspect.pointcut.LoggedRequestPointCut.LogRequest()") 
    public void logRequest(){ 
     System.out.println("Method Executed!"); 
     LOG.debug("Method Executed!"); 
    } 
} 

А для класса аннотаций:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface LoggedRequest { 
} 

И наконец Pointcut:

public class LoggedRequestPointCut { 

    @Pointcut("execution(@com.application.aspect.annotation.LoggedRequest * *(..))") 
    public void LogRequest(){} 

} 

Теперь наверняка, у меня есть аннотировал требуемый метод api в моем контроллере:

Как было предложено многими другими ответами на SO. Я добавил следующее к моей конфигурации пружины:

<context:annotation-config/> 
... 
<context:component-scan base-package="com.application.core"/> 
... 
<aop:aspectj-autoproxy /> 

Теперь все это не работает. Я имею в виду, что по моему API-вызову /login требуемый совет не выполняется.

+0

И ГДЕ Вы добавили ''? Потому что если это в контексте вашего корневого приложения (т. Е. 'ContextLoaderListener'), это ничего не сделает для ваших контроллеров. Рядом с этим вы должны включить 'proxy-target-class =" true "' в '', а также заставить его работать для контроллеров. –

+0

Попробуйте изменить от: '@Pointcut (исполнение (@ com.application.aspect.annotation.LoggedRequest * * (..))' к '@Pointcut (@annotation (com.application. aspect.annotation.LoggedRequest)) ' , а затем попытайтесь вызвать ваши аннотированные методы. – mlewandowski

+0

У вас есть' spring-aop' и 'aspectjweaver' в вашем пути к классу? –

ответ

2

При использовании АОП на бобах в Spring, которая применяется только к бобам в том же контексте приложения.

В типичном веб-приложении у вас будет ContextLoaderListener и DispatcherServlet, оба из которых создают ApplicationContext. ContextLoaderListener создает так называемый контекст корневого приложения и DispatcherServlet дочерний контекст с отношением к корневому контексту.

Конфигурация АОП из корня не влияет на компоненты в дочернем контексте, а конфигурация АОП в дочернем контексте не влияет на компоненты в корневом контексте.

Теперь вы настроили аспект и <aop:aspectj-autoproxy /> в корневом контексте и за исключением того, что он работает для компонента, который живет в дочернем контексте. Это, очевидно, не сработает. Переместите (или дублируйте) эту конфигурацию в дочерний контекст.

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

+0

Что это значит для меня, если я настроил свой контекст с аннотациями? Я добавил @EnableAspectJAutoProxy в свой класс конфигурации, а также добавил компонентный компонент, и он не работает ... Как я могу контролировать, в каком контексте создается созданный в этом случае автопрокси? – Jardo

+0

Неважно, где вы его положили. Если конфигурация загружена в корневом контексте, а bean to proxy находится в дочернем (или родительском) контексте, это не сработает. Не имеет значения, используете ли вы файлы xml, java или property (или любые другие средства) для создания «ApplicationContext». –

+0

Хорошо, но как я могу убедиться, что конфигурация АОП и компонент для прокси-сервера находятся в одном контексте? – Jardo

0

все это кажется нормально, но вы должны написать вещь, как это:

<aop:aspectj-autoproxy > 
     <aop:include name="loggedRequestAspect"/> 
    </aop:aspectj-autoproxy> 

, потому что с этой окончательной конфигурации вы говорите на весеннем autoproxy инфраструктуры, что бобы рассмотреть в процессе автоматического проксирования. Ключевой вопрос: если вы хотите использовать аспект для входа в метод вызова метода, это нормально, но если вы хотите использовать аспект для регистрации HTTP-вызова, это не будет работать, в этом случае может быть хорошим выбором использовать перехватчик ,

Вы можете использовать ваши org.springframework.web.servlet.HandlerInterceptor или org.springframework.web.context.request.WebRequestInterceptor реализации

, а затем зарегистрировать его в org.springframework.web.servlet.config .annotation.WebMvcConfigurerAdapter так:

@Configuration 
class MyWebConfiguratio extends WebMvcConfigurerAdapter { 
.... 
     @Override 
     public void addInterceptors(InterceptorRegistry registry) { 
      registry.addInterceptor(new HandlerInterceptor() { 
       ... 
      }).addPathPatterns("...."); 
      registry.addInterceptor(new WebMvcConfigurerAdapter() { 
       .... 
      }).addPathPatterns("...."); 
     } 

     .... 
} 

в Java конфигурации или

<mvc:interceptors> 
     <bean id="localeChangeInterceptor" 
       class="com.yourapp.Interceptor""/> 
    </mvc:interceptors> 

в файле конфигурации XML с Пространство имен MVC

Я надеюсь, что это может помочь вам

+0

такая конфигурация, которую я использовал в своей работе, и она отлично работает для меня –

Смежные вопросы