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

时间:2012-11-27 03:22:10

标签: spring aop spring-aop

我有一个从应用程序上下文中获取的ShapeService。 shapeService注入了Circle和Triangle。我在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被触发而不是apllicationContext的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());

    }
}

由于

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

正如@Dave暗示的那样,要在编译时(CTW)或在类加载时间(LTW)启用必须“编织”它们的方面。

为了从AspectJ + Spring魔术中受益,请考虑使用例如LTW,非常灵活(您甚至可以在不修改它们的情况下将方面编织到第三方罐子中)。

首先阅读the Spring Documentation,这是一个很好的切入点。 基本上是:

  • 在Spring配置中放置一个<context:load-time-weaver/>元素
  • 在类路径中创建一个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