Зависимость Autowired не внедряется в Aspect in Spring MVC

Я не могу @Autowire создать экземпляр сервисного уровня в Aspect. В Aspect ссылка на bean-компонент @Autowired имеет значение NULL и выдает NullPointerException. Любая помощь будет высоко ценится. Думаю, я накосячил с конфигурацией.

Ниже мой servlet-context.xml:

<!-- Activates various annotations to be detected in bean classes -->
<context:annotation-config />
<context:spring-configured />       

<!-- Scans the classpath of this application for @Components to deploy as beans -->
<context:component-scan base-package="xx.yy" />

<!--  an @AspectJ aspect will be interpreted as an aspect by Spring AOP and beans in the context will be advised accordingly -->
<aop:aspectj-autoproxy />

<beans:bean id="loggingAspect" class="xx.yy.aop.aspects.LoggingAspect" />
<beans:bean id="authenticationAspect" class="xx.yy.aop.aspects.AuthenticationAspect" />

<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />

Ниже приведен мой Аспект:

@Configurable
@Component
@Aspect
public class AuthenticationAspect {
private static final Logger logger = LoggerFactory.getLogger(AuthenticationAspect.class);

@Autowired
private LoginService loginService;

    //.... 
}

Вот мой контроллер, использующий аннотацию @Authentication, определенную выше:

@Controller
@RequestMapping("/user")
public class UsersController {

@Autowired
private UserService userService;

@Authenticate
@RequestMapping(value="/{userId}/profile", method=RequestMethod.GET)    
public String displayUser(WebRequest webRequest, @PathVariable("userId") String userId, Model model) {
    User user = userService.findUser(Long.valueOf(userId));  
    model.addAttribute("user", user);
    model.addAttribute("AccordionMenuTab","5");
    model.addAttribute("selectedLink","profile");
    return "profile";
}

Я получаю следующее исключение:

Oct 8, 2011 3:12:48 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet appServlet threw exception
java.lang.NullPointerException
    at xx.yy.controller.UsersController.displayUser_aroundBody1$advice(UsersController.java:28)
    at xx.yy.controller.UsersController.displayUser(UsersController.java:1)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:426)
    at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:790)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)

person MUHAMMAD KHAN    schedule 07.10.2011    source источник


Ответы (2)


См. эту часть. документации:

7.8.3 Настройка аспектов AspectJ с использованием Spring IoC

При использовании аспектов AspectJ с приложениями Spring естественно хотеть и ожидать возможности настройки таких аспектов с помощью Spring. Сама среда выполнения AspectJ отвечает за создание аспектов, а средства настройки аспектов, созданных AspectJ, через Spring зависят от модели создания экземпляров AspectJ (предложение «per-xxx»), используемой аспектом.

Большинство аспектов AspectJ являются одноэлементными аспектами. Конфигурация этих аспектов очень проста: просто создайте определение bean-компонента, ссылаясь на тип аспекта, как обычно, и включите атрибут bean-компонента 'factory-method=aspectOf'. Это гарантирует, что Spring получит экземпляр аспекта, запросив его у AspectJ, а не пытаясь создать экземпляр сам. Например:

<bean id="profiler" class="com.xyz.profiler.Profiler"
      factory-method="aspectOf" />
person Bozho    schedule 08.10.2011
comment
документ громоздкий, но король. - person engineer; 21.05.2014
comment
добавление factory-method=aspectOf решило мою проблему, спасибо!! - person sjaiswal; 17.05.2016
comment
Привет, ты знаешь, как перевести в конфигурацию Java? - person Sofiane; 07.07.2017

Для тех, кто ищет конфигурацию bean-компонента на основе java, используя отражения java, я мог бы заархивировать то же самое

@Bean
public ExceptionAspectHandler exceptionAspectHandler(){
    try
    {
        //noinspection JavaReflectionMemberAccess
        Method method = ExceptionAspectHandler.class.getMethod("aspectOf" );
        return (ExceptionAspectHandler) method.invoke(null);
    }
    catch( IllegalAccessException | InvocationTargetException | NoSuchMethodException e )
    {
       logger.log( Level.SEVERE, "Error creating bean : ", e );
    }
    return null;
}

Поскольку метод aspectOf() недоступен во время компиляции, мы не можем создать компонент, просто вызвав метод. Вот почему конфигурация XML способна справиться с этим.

Альтернативный более простой подход

@Bean
public ExceptionAspectHandler exceptionAspectHandler()
{
    return Aspects.aspectOf( ExceptionAspectHandler.class );
}

Это тоже работает.

person Tanimak    schedule 28.11.2020