0

我有一个从应用程序上下文中获得的 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 被触发,而不是 appllicationContext 的 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());

    }
}

谢谢

4

2 回答 2

1

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

于 2012-11-27T06:44:35.173 回答
0

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

为了从 AspectJ+Spring 的魔力中受益,可以考虑使用例如 LTW,它非常灵活(您甚至可以将方面从 3rd-party jar 中编织到类中而无需修改它们)。

从阅读Spring 文档开始,这是一个很好的切入点。基本上:

  • <context:load-time-weaver/>在你的 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
于 2012-11-27T11:22:55.893 回答