Spring AOP 建议不适用于所有控制器,仅适用于一个控制器
Spring AOP Advise not work for all controller, work for one controller only
在下面找到我创建的代码。
我想记录(AOP Advice before,after etc.)所有控制器方法,
但是建议只执行一个控制器(AuthenticationController)方法,在第二个控制器(UserManagerController)上建议不应用方法,两个控制器都在同一个包中(com.framework.controller),但我不知道出了什么问题?为什么它只适用于一个控制器而不适用于其他控制器。
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
applicationContext.xml
<!-- Used to activate applied annotations in already registered beans in application context -->
<!-- Declares support for general annotations such as @Required, @Autowired, @PostConstruct, and so on -->
<context:annotation-config />
<context:component-scan base-package="com.framework.*"/>
<!-- ***************************************************************** -->
<!-- Declares explicit support for annotation-driven MVC controllers (i.e. @RequestMapping, @Controller, @RequestBody/ResponseBody) -->
<mvc:annotation-driven />
<!-- Logging Aspect -->
<bean id="frameworkLoggingAspect" class="com.framework.aspect.FrameworkLoggingAspect" />
<!-- Enable @AspectJ annotation support -->
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="frameworkLoggingAspect" />
</aop:aspectj-autoproxy>
寻找我的长相class
FrameworkLoggingAspect.java
@Aspect
public class FrameworkLoggingAspect {
@Pointcut("execution(* com.framework.controller.*.*(..))")
public void beforeControllerMethod() {
}
@Pointcut("execution(* com.framework.controller.*.*(..))")
public void afterControllerMethod() {
}
@Before("beforeControllerMethod()")
public void logBeforeAllMethods(JoinPoint joinPoint) {
CustomLogger.info(" Before Name " + joinPoint.getSignature().getName());
CustomLogger.info(" Before Modifier " + joinPoint.getSignature().getModifiers());
}
@After("afterControllerMethod()")
public void logAfterAllMethods(JoinPoint joinPoint) {
CustomLogger.info(" After Name " + joinPoint.getSignature().getName());
CustomLogger.info(" After Modifier " + joinPoint.getSignature().getModifiers());
}}
查找控制器包(com.framework.controller)
AuthenticationController.java
@Controller
@RequestMapping("/authentication")
public class AuthenticationController {
@Autowired
AuthenticationService authenticationService;
@RequestMapping(value = "loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside Login Page");
return new ModelAndView("user.login", map);
}
@RequestMapping(value = "logout", method = RequestMethod.GET)
public ModelAndView loginOut(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside logout Page");
return new ModelAndView("user.login", map);
}
@RequestMapping(value = "validateUser", method = RequestMethod.POST)
public ModelAndView validateUser(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside validate user Page");
return new ModelAndView("user.dashboard", map);
}
}
UserManagerController.java
@Controller
@RequestMapping("/userManager")
public class UserManagerController {
@Autowired
UserManagerService userManagerService;
@RequestMapping(value = "view", method = RequestMethod.GET)
ModelAndView view(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside User View Page");
return new ModelAndView("user.manager.view", map);
}
@RequestMapping(value = "saveUser", method = RequestMethod.POST)
ModelAndView saveUser(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside Save User");
return new ModelAndView("user.manager.view", map);
}}
在下面找到我得到的输出
below controller(FrameworkLoggingAspect) advise applying properly
advise before for method loginPage
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : Before Name loginPage
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : Before Modifier 1
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.controller.AuthenticationController : Inside Login Page
advise after for method loginPage
INFO 2017-10-03 13:32:40,427 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : After Name loginPage
INFO 2017-10-03 13:32:40,427 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : After Modifier 1
advise before for method validateUser
INFO 2017-10-03 13:33:15,292 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : Before Name validateUser
INFO 2017-10-03 13:33:15,293 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : Before Modifier 1
INFO 2017-10-03 13:33:15,293 [http-nio-8080-exec-6] - com.framework.controller.AuthenticationController : Inside validate user Page
advise after for method validateUser
INFO 2017-10-03 13:33:15,294 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : After Name validateUser
INFO 2017-10-03 13:33:15,294 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : After Modifier 1
but in this controller(UserManagerController) advise not applying
INFO 2017-10-03 13:34:18,467 [http-nio-8080-exec-9] - com.framework.controller.UserManagerController : Inside User View Page
请帮我解决这个问题,我知道这是个愚蠢的问题,并且已经发布了很多教程,但请相信我,我已经把它扔掉了,但我仍然不明白哪里出了问题?
UserManagerController 中的方法是包可见的。它们可能需要 public(取决于您的 Spring 版本)。对于 CGLib,Spring 3.2.18 recommends public method signatures, whereas Spring 5 can intercept public and protected methods (and, according to the note in the documentation、"even package-visible methods if necessary")。
在下面找到我创建的代码。
我想记录(AOP Advice before,after etc.)所有控制器方法, 但是建议只执行一个控制器(AuthenticationController)方法,在第二个控制器(UserManagerController)上建议不应用方法,两个控制器都在同一个包中(com.framework.controller),但我不知道出了什么问题?为什么它只适用于一个控制器而不适用于其他控制器。
web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
applicationContext.xml
<!-- Used to activate applied annotations in already registered beans in application context -->
<!-- Declares support for general annotations such as @Required, @Autowired, @PostConstruct, and so on -->
<context:annotation-config />
<context:component-scan base-package="com.framework.*"/>
<!-- ***************************************************************** -->
<!-- Declares explicit support for annotation-driven MVC controllers (i.e. @RequestMapping, @Controller, @RequestBody/ResponseBody) -->
<mvc:annotation-driven />
<!-- Logging Aspect -->
<bean id="frameworkLoggingAspect" class="com.framework.aspect.FrameworkLoggingAspect" />
<!-- Enable @AspectJ annotation support -->
<aop:aspectj-autoproxy proxy-target-class="true">
<aop:include name="frameworkLoggingAspect" />
</aop:aspectj-autoproxy>
寻找我的长相class FrameworkLoggingAspect.java
@Aspect
public class FrameworkLoggingAspect {
@Pointcut("execution(* com.framework.controller.*.*(..))")
public void beforeControllerMethod() {
}
@Pointcut("execution(* com.framework.controller.*.*(..))")
public void afterControllerMethod() {
}
@Before("beforeControllerMethod()")
public void logBeforeAllMethods(JoinPoint joinPoint) {
CustomLogger.info(" Before Name " + joinPoint.getSignature().getName());
CustomLogger.info(" Before Modifier " + joinPoint.getSignature().getModifiers());
}
@After("afterControllerMethod()")
public void logAfterAllMethods(JoinPoint joinPoint) {
CustomLogger.info(" After Name " + joinPoint.getSignature().getName());
CustomLogger.info(" After Modifier " + joinPoint.getSignature().getModifiers());
}}
查找控制器包(com.framework.controller)
AuthenticationController.java
@Controller
@RequestMapping("/authentication")
public class AuthenticationController {
@Autowired
AuthenticationService authenticationService;
@RequestMapping(value = "loginPage", method = RequestMethod.GET)
public ModelAndView loginPage(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside Login Page");
return new ModelAndView("user.login", map);
}
@RequestMapping(value = "logout", method = RequestMethod.GET)
public ModelAndView loginOut(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside logout Page");
return new ModelAndView("user.login", map);
}
@RequestMapping(value = "validateUser", method = RequestMethod.POST)
public ModelAndView validateUser(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside validate user Page");
return new ModelAndView("user.dashboard", map);
}
}
UserManagerController.java
@Controller
@RequestMapping("/userManager")
public class UserManagerController {
@Autowired
UserManagerService userManagerService;
@RequestMapping(value = "view", method = RequestMethod.GET)
ModelAndView view(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside User View Page");
return new ModelAndView("user.manager.view", map);
}
@RequestMapping(value = "saveUser", method = RequestMethod.POST)
ModelAndView saveUser(HttpServletRequest request, HttpServletResponse response) {
ModelMap map = new ModelMap();
CustomLogger.info("Inside Save User");
return new ModelAndView("user.manager.view", map);
}}
在下面找到我得到的输出
below controller(FrameworkLoggingAspect) advise applying properly
advise before for method loginPage
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : Before Name loginPage
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : Before Modifier 1
INFO 2017-10-03 13:32:40,426 [http-nio-8080-exec-10] - com.framework.controller.AuthenticationController : Inside Login Page
advise after for method loginPage
INFO 2017-10-03 13:32:40,427 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : After Name loginPage
INFO 2017-10-03 13:32:40,427 [http-nio-8080-exec-10] - com.framework.aspect.FrameworkLoggingAspect : After Modifier 1
advise before for method validateUser
INFO 2017-10-03 13:33:15,292 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : Before Name validateUser
INFO 2017-10-03 13:33:15,293 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : Before Modifier 1
INFO 2017-10-03 13:33:15,293 [http-nio-8080-exec-6] - com.framework.controller.AuthenticationController : Inside validate user Page
advise after for method validateUser
INFO 2017-10-03 13:33:15,294 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : After Name validateUser
INFO 2017-10-03 13:33:15,294 [http-nio-8080-exec-6] - com.framework.aspect.FrameworkLoggingAspect : After Modifier 1
but in this controller(UserManagerController) advise not applying
INFO 2017-10-03 13:34:18,467 [http-nio-8080-exec-9] - com.framework.controller.UserManagerController : Inside User View Page
请帮我解决这个问题,我知道这是个愚蠢的问题,并且已经发布了很多教程,但请相信我,我已经把它扔掉了,但我仍然不明白哪里出了问题?
UserManagerController 中的方法是包可见的。它们可能需要 public(取决于您的 Spring 版本)。对于 CGLib,Spring 3.2.18 recommends public method signatures, whereas Spring 5 can intercept public and protected methods (and, according to the note in the documentation、"even package-visible methods if necessary")。