Spring getBean()的AOP通配符未被触发

Spring getBean()的AOP通配符未被触发,spring,aop,spring-aop,Spring,Aop,Spring Aop,我有一个ShapeService,它是从应用程序上下文获得的。shapeService注入了一个圆和三角形。我的shapeService中有getCircle()和getTriangle()。我还有一个建议,它被配置为在调用getter时触发。指定的切入点表达式,它适用于所有getter。因此,无论何时调用getCircle()或getTriangle(),都会触发通知。但我想知道为什么applicationContext.getBean()不会触发这种情况。这也是一个满足切入点表达式的gett

我有一个ShapeService,它是从应用程序上下文获得的。shapeService注入了一个圆和三角形。我的shapeService中有getCircle()和getTriangle()。我还有一个建议,它被配置为在调用getter时触发。指定的切入点表达式,它适用于所有getter。因此,无论何时调用getCircle()或getTriangle(),都会触发通知。但我想知道为什么applicationContext.getBean()不会触发这种情况。这也是一个满足切入点表达式的getter。有人能帮我弄清楚为什么它没有被触发吗

@Aspect
@Component
    public class LoggingAspect {

    @Before("allGetters()")
    public void loggingAdvice(JoinPoint joinPoint){
        System.out.println(joinPoint.getTarget());
    }

    @Pointcut("execution(public * get*(..))")
    public void allGetters(){}
}
这是获取bean的主类。只有Shapeservice的getter和circle的getter被触发,而不是ApplicationContext的getBean

public class AopMain {
        public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
        ShapeService shapeService = ctx.getBean("shapeService", ShapeService.class);
        System.out.println(shapeService.getCircle().getName());

    }
}

感谢您,应用程序上下文不是Spring组件(它是管理其他组件的容器),因此如果您使用Spring AOP,它不会自行编织。如果您使用AspectJ,您可以拦截所有getter,但即使如此,也只能通过加载时编织或重新编译类路径上的所有jar。

正如@Dave所暗示的,要启用方面,您必须在编译时()或类加载时()对其进行“编织”

为了从AspectJ+Spring魔术中获益,考虑使用LTW,这是相当灵活的(可以在第三个JAR的类中甚至不修改它们的情况下编织方面)。 从阅读开始,这是一个很好的切入点。 基本上:

  • 在Spring配置中放置一个
    元素
  • 在类路径中创建一个
    META-INF/aop.xml
    文件:

    <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
    <aspectj>
      <weaver>
        <!-- include your application-specific packages/classes -->
        <!-- Nota: you HAVE TO include your aspect class(es) too! -->
        <include within="foo.ShapeService"/>
        <include within="foo.LoggingAspect"/>
      </weaver>
      <aspects>
        <!-- weave in your aspect(s) -->        
        <aspect name="foo.LoggingAspect"/>
      </aspects>
    </aspectj>
    
    
    
  • 使用编织java代理运行:
    java-javaagent:/path/to/lib/spring-instrument.jar foo.Main