Spring 带有 AspectJ 的 MVC

Spring MVC with AspectJ

我有一个正在运行的 spring mvc 项目。我想使用 AspectJ 通过我的控制器记录每个请求。相关代码:

控制器:(在包 hu.freetime.controller 中)

@Controller
@RequestMapping("/")
public class BaseControllerImpl {
    @RequestMapping(method = RequestMethod.GET)
    public String index(Model model) {
        return "index";
    }
}

看点:

@Aspect
public class ControllerAspectImpl {
    Logger logger = LoggerFactory.getLogger(ControllerAspectImpl.class);

    @Pointcut("execution(public * hu.freetime.controller.BaseControllerImpl.*(..))")
    public void logController() {
    }


    @Around("logController()")
    public void log(final ProceedingJoinPoint pjp) {
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        logger.info("Calling Controller method: " + method.getName() + "()");
        try {
            pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }
}

WebAppInitializer:

public class CashflowWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { RootConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
}

WebConfig class:

@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@ComponentScan(basePackages = { "hu.freetime.controller", "hu.freetime.aspect" })
public class WebConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setExposeContextBeansAsAttributes(true);
        return resolver;
    }

    @Bean
    public ControllerAspectImpl getControllerAspect() {
        return new ControllerAspectImpl();
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}

问题是,两个组件中只有一个在工作。如果我 "turn off" AOP,MVC 工作完美,但是当我 "turn on",我想转到主页时,我得到这个错误:

HTTP Status 404 - .../WEB-INF/views/.jsp
The requested resource is not available.

奇怪的是它想映射“.jsp”而不是"index.jsp",正如我在Controller 的index() 方法中所写的那样。我在运行时调试,确实停在controller方法处

我怎样才能让它发挥作用?

使用下面的代码就可以了

@Pointcut("execution(public * hu.freetime.*(..))")

您的 around 建议不是 return pjp.proceed() 的结果。那是建议方法的 return 值,并且 必须由建议 return 编辑! 否则你也会将建议方法变成无效。

public **Object** log(final ProceedingJoinPoint pjp) {
...
    try {
        **return** pjp.proceed(); <<< !
    } catch (Throwable e) {
        e.printStackTrace();
    }    
}