Java 方面不从计划中捕获方法

Java 方面不从计划中捕获方法,java,spring,annotations,scheduler,spring-aop,Java,Spring,Annotations,Scheduler,Spring Aop,当注释的set方面被设置为cron中的方法时,为什么它不起作用 @Component public class MyClass { @Scheduled(cron = "0/5 * * * * ?") public void schedule() { myMethod("test"); } @MyAnno(cl = MyClass.class, description = "desc") private void myMethod(String text) {

当注释的set方面被设置为cron中的方法时,为什么它不起作用

@Component
public class MyClass {
  @Scheduled(cron = "0/5 * * * * ?")
  public void schedule() {
    myMethod("test");
  }

  @MyAnno(cl = MyClass.class, description = "desc")
  private void myMethod(String text) {

  }
}

@Aspect
@Component
public MyAscpect {
  @Before("@annotation(myAnnoAnnotation)")
  public void myAnnoAspect(JoinPoint jp, MyAnno myAnnoAnnotation) {
}
面向方面编程 以下是您应该记住的关于Spring AOP的要点

  • 由于Spring的AOP框架基于代理的特性,根据定义,不会拦截目标对象中的调用

  • 对于JDK代理,只能拦截代理上的公共接口方法调用。使用CGLIB,代理上的publicprotected方法调用将被拦截,甚至包可见方法(如果需要)

  • 你可以找到更多

    • 由于您的方法
      myMethod
      private,因此不会拦截对
      myMethod
      的调用。请参阅上文提到的第二点
    • 即使您的
      myMethod
      public,如果调用是通过
      schedule
      方法进行的,对
      myMethod
      的调用也不会被拦截。请参考上文提到的第一点
    • 现在,如果您的
      myMethod
      public,那么如果从对象外部直接调用
      myMethod
      方法,则会拦截对
      myMethod
      的调用
    AspectJ源代码编织 但是,您可以通过利用AspectJ源代码编织来拦截私有方法。在源代码编织中,编织者成为编译器的一部分。 weaver通过处理源代码并生成编织的Java字节码来充当编译器。它不使用
    javac
    编译器,而是使用
    ajc
    编译器

    以下是您需要进行的更改:

    • 将Maven
      aspectj Maven插件添加到您的
      pom.xml
    • 如下所示,将
      MyAspect
      的切入点更改为包含private方法

      @Component
      @Aspect
      public class MyAspect {
      
          @Before("@annotation(myAnnoAnnotation) && execution(private * *(..))")
          public void myAnnoAspect(JoinPoint jp, MyAnno myAnnoAnnotation) {
          ...
          }
      }
      
      您可以找到一个完整的工作示例


    尝试按以下方式更改来源

    当然,带有main方法的应用程序类应该附加@EnableScheduling

    @Component
    public class MyClass {
        @MyAnno
        @Scheduled(cron = "0/5 * * * * ?")
        public void schedule() {
            myMethod("test");
        }
        private void myMethod(String text) {
            //TODO enter your code.
        }
    }
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnno{
    
    }
    
    @Aspect
    @Component
    public class MyAnnoAspect{
        @Before("@annotation(MyAnno)")
        public void myAnnoAspect(JoinPoint jp) {
    
        }
    }
    

    这里的问题到底是什么。你能说清楚吗。在不同的方法上有
    @scehduled
    ,在不同的方法上有
    @MyAnno
    。这有什么关系?MyAnnoSpect方法在调用myMethod后从不执行。我对另一个批注有相同的类结构,并且它可以工作(没有@Scheduled)。在
    批注之前有
    ,这意味着
    MyAnnoSpect
    应该在
    myMethod
    之前执行