如何在Spring 3中将@Aspect与@Controller结合起来?

chz*_*gla 7 java model-view-controller aop spring aspectj

我正在尝试使用@Controller,基于注释的方法设置Spring 3 Web MVC项目.

package my.package

@Controller
@RequestMapping("/admin/*")
public class AdminMultiActionController {

@RequestMapping(value = "admin.htm", method = RequestMethod.GET)
public String showAdminSection() {
    return "admin";
}
Run Code Online (Sandbox Code Playgroud)

我的dispatcher-servlet具有以下Controller处理程序:

<context:component-scan base-package="my.package" />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
Run Code Online (Sandbox Code Playgroud)

使用提供的maven工件,webapp运行良好:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>3.0.2.RELEASE</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

现在我想添加@AspectJ AOP.我得到了libs:

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.9</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.9</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

添加到我的applicationContext.xml:

<aop:aspectj-autoproxy/>
Run Code Online (Sandbox Code Playgroud)

确保在applicationContext.xml中创建相关的bean:

<bean id="securityInterceptor" class="my.package.service.SecurityInterceptor"/>
Run Code Online (Sandbox Code Playgroud)

并开始充实@Aspect:

package my.package.service

@Aspect
public class SecurityInterceptor {

@Pointcut("execution(* showAdminSection(..))")// the pointcut expression
private void foo() {
    System.out.println("fooo");
}// the pointcut signature
Run Code Online (Sandbox Code Playgroud)

现在这就是它停止工作的地方.永远不会打印"fooo".

可能是,因为切入点(拼写?)对象必须是弹簧管理的bean,而我的@Controller与DefaultAnnotationHandlerMapping一起被认为不是这样的?

任何帮助,将不胜感激.如果我忘记包含任何信息,请询问.希望有人可以帮助我.

非常感谢!

chz*_*gla 8

唉上帝......终于搞定了!

谢谢你的回复Affe!

对于好奇:

  1. 不要使用组件扫描和defaultannotationhandler来获取控制器
  2. 用弹簧xml连接它们
  3. 当aop config位于applicationContext中时,在dispatcher-servlet中没有所述控制器.
  4. 将两者都移到dispatcher-servlet

  5. 当然Affe是对的:不要忘记建议:p

  • 点3对我来说有点缺失,谢谢:) (2认同)

Sci*_*r24 7

对于第二个chzbrgla,对于那些稍后查看的人(像我一样),我的问题在将控制器组件扫描和aop配置移动到调度程序servlet之后解决了,如下所示:

...
<context:component-scan base-package="com.mypackage.controller"/>
<!--  Configure aspects. -->
<bean id="myAspect1" class="com.mypackage.intercept.SiteAccessAspect"/>

<aop:aspectj-autoproxy proxy-target-class="true">
    <aop:include name="myAspect1" />
</aop:aspectj-autoproxy>
...
Run Code Online (Sandbox Code Playgroud)

如您所见,组件扫描仍然适用于我的情况.移动到调度程序servlet解决了它.

apspect(在本例中为myApect1)配置如下:

@Pointcut("within(@org.springframework.stereotype.Controller *)")
public void controller() {}

@Pointcut("execution(* *(..))")
public void method() {}

@Before("controller() && method()")
public void doAccessCheck(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature()); // For testing purposes.
}
Run Code Online (Sandbox Code Playgroud)


Aff*_*ffe 4

切入点方法定义了切入点,它不会在匹配时被调用,您需要定义实际发生的事情。例如,

@Before("foo()")
public void beforeFoo(JoinPoint joinPoint) {
    System.out.println("foooo");
}
Run Code Online (Sandbox Code Playgroud)