【发布时间】:2016-01-26 18:21:00
【问题描述】:
我很难在 Spring MVC 项目中使用方面。
作为切入点的方法运行良好,但没有建议。
这是启动整个 Spring Boot 的类,它是 Spring 上下文的根:
@Lazy
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass=true)
@Configuration
public class MainSpringBootClass{
public static void main(String[] args)
{
SpringApplication.run(MainSpringBootClass.class, args);
}
}
这里是类和方法,也就是切入点。
@Component
@Log
@Aspect
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class MyExampleClass
{
public void example()
{
System.out.println("example");
}
}
这是我的方面:
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class MyAspect implements MethodBeforeAdvice
{
@Pointcut("execution(* com.example.MyExampleClass.example())")
public void asd()
{
// pointcut
}
@Before("asd()")
public void login()
{
System.out.println("im am logging in");
}
@Before("execution(* com.example.MyExampleClass.example())")
public void login2()
{
System.out.println("im am logging in2");
}
@Override
public void before(Method method, Object[] args, Object target) throws Throwable
{
System.out.println("aop before");
}
}
这是我的控制器:
@RestController
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class MyExampleController
{
private final MyExampleClass myExampleClass;
@Inject
public AdController(MyExampleClass myExampleClass)
{
this.myExampleClass = myExampleClass;
}
@RequestMapping("/")
public String index()
{
myExampleClass.example();
return "x";
}
}
如您所见,我一直在尝试使用注释来暴力破解正确的结果。 我也在一些网站上看到,我需要特定的依赖项,所以这是我的(仅粘贴与方面相关的那些):
compile 'org.springframework:spring-aop:+'
compile 'org.aspectj:aspectjrt:+'
compile 'org.aspectj:aspectjweaver:+'
compile 'cglib:cglib:+'
compile 'cglib:cglib-nodep:+'
所有依赖都已成功下载,项目编译运行正常。 当我点击 localhost:8080 时,我看到返回值“x”,在日志中我看到“示例”。 但是,我没有看到来自 spring aop 和 aspectj 的任何建议——我做错了什么?
我只是将这个项目用作沙箱来学习方面,所以我很想学习如何使用 Spring AOP 和 AspectJ 来学习。 对我来说最重要的是不使用 XML。
编辑: 我已经使用 println 向 MyAspect 添加了简单的构造函数来检查它是否已创建(毕竟它是带有 @Component 的普通 spring bean)并且确实如此 - 它是由 spring 正确创建的。
编辑 2: IntelliJ IDEA 告诉我有关方法 login 和 login2 的信息:“此建议不建议任何方法”,但同时,我能够从字符串中跳转(使用 control-click),这是注释中的值以正确实现。
【问题讨论】:
-
可以尝试的方法是确保您的切入点语法没有遗漏任何内容。例如如果您尝试像这样扩展它会怎样:
@Before("execution(* com.example.MyExampleClass.*(..))") -
它是正确的 - IntelliJ IDEA 让我跳到正确的方法,当我控制单击它时。我也尝试用 * 添加两个点和登机范围 - 仍然没有预期的输出(但一切都运行)。
-
可能是依赖问题?您可以尝试使用mvnrepository.com/artifact/org.springframework.boot/… 而不是mvnrepository.com/artifact/org.springframework/spring-aop (最初您可以尝试通过取出aspectj 引用来简化,看看它是否有效)
-
我已按照您的建议替换了 AOP 的依赖项 - 没有任何变化。沿 @Aspect 注释移除 AspectJ 依赖也无济于事。
-
@EnableAspectJAutoProxy只需要在@Configuration课程上一次,而不是在每个课程上...
标签: spring spring-mvc aspectj spring-aop