【问题标题】:spring mvc + spring aop + aspectjspring mvc + spring aop + aspectj
【发布时间】: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


【解决方案1】:

你只需要这样的东西:

@Aspect
@Component
public class MyAspect {

    @Before("execution(* com.example.MyExampleClass.example(..))")
    public void logBefore(JoinPoint pjp) throws Throwable {
        System.out.println("before...");
    }
}

您可能必须将所有 aspectJ 依赖项替换为 spring-boot-starter-aop

这是一个有效的示例项目(请参阅RestControllerAspect.java):

https://github.com/khoubyari/spring-boot-rest-example

【讨论】:

  • 它适用于@Before 建议...打印出消息,控制器完成它的任务。 github.com/khoubyari/spring-boot-rest-example/blob/master/src/…
  • 我尝试将两种 login() 方法都替换为 public void login(JoinPoint pjp) throws Throwable 它不会改变任何东西。此外,这个 pjp 甚至没有方法继续(但它有其他方法)。我也查看了这个项目并比较了进口 - 我有非常相似的。
  • 有趣。我原以为如果按照上面项目的方式,按照spring-boot简单配置AOP(包括依赖管理部分),应该可以得到同样的结果。在项目中,切入点略有不同,但这应该不是问题。还要注意任何地方都没有EnableAspectJAutoProxy
猜你喜欢
  • 2015-12-17
  • 2010-12-09
  • 2012-07-25
  • 2012-03-28
  • 2015-01-20
  • 1970-01-01
  • 1970-01-01
  • 2015-12-01
  • 1970-01-01
相关资源
最近更新 更多