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();
}
}
我有一个正在运行的 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();
}
}