Java 如何为抽象方法创建切入点

Java 如何为抽象方法创建切入点,java,spring,spring-aop,Java,Spring,Spring Aop,我试图为在子类中实现的抽象方法创建切入点,但从未调用AOP 以下是我的最小Java代码: package com.example; public class Service { private ParentAbstractClass clazz; public Service(ParentAbstractClass clazz) { this.clazz = clazz; } public void process() { c

我试图为在子类中实现的抽象方法创建切入点,但从未调用AOP

以下是我的最小Java代码:

package com.example;

public class Service {
    private ParentAbstractClass clazz;

    public Service(ParentAbstractClass clazz) {
        this.clazz = clazz;
    }

    public void process() {
        clazz.method();
    }
}
这是一个服务类,它具有要注入的类的抽象,并调用一个方法

我的抽象类有一些公共逻辑和一个特定于实现的代码,这是一个抽象方法

package com.example;

import java.util.List;

public abstract class ParentAbstractClass {
    public void method() {
        abstractMethod(List.of("test"));
    }

    public abstract void abstractMethod(List<String> names);
}
package com.example;

import java.util.List;

public class ConcreteClass extends ParentAbstractClass {
    @Override
    public void abstractMethod(List<String> names) {
        System.out.println("Look up! AOP should have executed");
    }
}
在我的
abstractMethod
中,我正在做一些本质上是事务性的事情,我有手动控制事务的业务需求,但是我的方面类从未被调用。有人能帮我找出我犯了什么错误吗


谢谢。

这个问题是由Spring AOP实现的约束引起的。以下是引用自:

由于Spring的AOP框架基于代理的特性,在 根据定义,目标对象不被拦截。对于JDK 代理,只能调用代理上的公共接口方法 拦截。对于CGLIB,在 代理被拦截(甚至包可见的方法,如果 (必要的)。但是,通过代理进行的公共交互应始终有效 通过公开签名进行设计

请注意,切入点定义通常与任何 拦截方法。如果一个切入点是严格意义上的公开, 即使在具有潜在非公开交互的CGLIB代理场景中 通过代理,需要相应地定义它

如果您的拦截需要包括方法调用甚至构造函数 在目标类中,考虑使用弹簧驱动的本机。 AspectJ编织代替了Spring基于代理的AOP框架。这 以不同的方式构成不同的AOP使用模式 特点,所以一定要熟悉编织 在做决定之前

因此,您有两种可能的方法来解决此问题:

  • 仅在其他bean调用的方法上使用方面(无自调用)
  • 使用AspectJ AOP实现。我准备了一个使用AspectJ编译时编织的简单示例,代码位于

  • AspectJ方法简而言之:

    按如下方式修改事务方面:

    package com.example;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class TxAspect {
    
        @Around("methodsToBeProfiled()")
        public void test(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("I am not going to do anything");
            pjp.proceed();
        }
    
        @Pointcut("execution(* com.example.ConcreteClass.abstractMethod(..))")
        public void methodsToBeProfiled(){}
    } 
    
      <bean id="clazz" class="com.example.ConcreteClass"/>
    
      <bean id="myservice" class="com.example.Service">
        <constructor-arg ref="clazz"/>
      </bean>
    
    减少XML配置,如下所示:

    package com.example;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    
    @Aspect
    public class TxAspect {
    
        @Around("methodsToBeProfiled()")
        public void test(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("I am not going to do anything");
            pjp.proceed();
        }
    
        @Pointcut("execution(* com.example.ConcreteClass.abstractMethod(..))")
        public void methodsToBeProfiled(){}
    } 
    
      <bean id="clazz" class="com.example.ConcreteClass"/>
    
      <bean id="myservice" class="com.example.Service">
        <constructor-arg ref="clazz"/>
      </bean>
    
    
    
    使用以下maven插件编译应用程序:

      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.11</version>
        <dependencies>
          <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjtools</artifactId>
            <version>${ascpectj.version}</version>
          </dependency>
        </dependencies>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <complianceLevel>1.8</complianceLevel>
        </configuration>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>test-compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    
    
    org.codehaus.mojo
    aspectj maven插件
    1.11
    org.aspectj
    aspectjtools
    ${aspectj.version}
    1.8
    1.8
    1.8
    编译
    测试编译
    
    感谢您提供参考。我会在一小时内给你赏金。如果我没有,请提醒我:)所以同时接受和奖励是有限制的。。