Spring AOP:没有触发建议

时间:2011-10-12 15:11:53

标签: spring aop spring-aop

尝试设计简单的方面,当任何公共方法执行时,将“logg”字词打印到控制台。

方面:

@Aspect
public class LoggingAspect {

    @Pointcut("execution(public * *(..))")
    public void publicServices() {
    };

    @Before("publicServices()")
    public void logg() {
        System.out.println("logg");
    }

}

xml config

    <context:component-scan base-package="aspectlogging" /> 
    <aop:aspectj-autoproxy/>
    <bean id="loggingAspectHolder" class="aspectlogging.LoggingAspect"/>

简单豆:

package aspectlogging;
@Component
    public class TestableBean {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
        }

试验:

public class TestLogging {
    public static void main(String[] args) {
        TestableBean tb = new TestableBean();
        tb.setName("yes");
        tb.getName();
    }
}

我希望,TestLogging的运行结果将在控制台中显示“ logg ”字样,并且不会返回任何输出。 在这种情况下,我能正确理解AOP吗?

2 个答案:

答案 0 :(得分:5)

使用@Around建议时,您需要在建议方法中使用ProceedingJoinPoint pjp参数,并在需要调用包装方法时在顾问程序中调用pjp.proceed()。真的很容易使用@Before建议,否则你所做的事情会正常工作。


[编辑]:此外,你必须让Spring为你构建你的bean,而不是直接调用new。这是因为bean对象实际上是真实对象(位于其中)的代理。因为您的目标对象没有实现接口,所以除了Spring库之外,还需要在类路径上使用cglib库。 (或者,您可以完全使用AspectJ,但这需要使用不同的编译器配置。)

要创建bean,首先需要创建一个Spring 上下文,然后查询bean实例。这意味着您可以从:

更改
TestableBean tb = new TestableBean();

To(假设您使用的是Spring 3,并且您的XML配置位于类路径中的某个“config.xml”中):

ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
TestableBean tb = context.getBean(TestableBean.class);

其余代码保持不变(在调整import语句和可能的其他依赖项之后)。

答案 1 :(得分:4)

在这一点上不太确定,但是你可能需要使用Spring管理的TestableBean让spring AOP选择方法调用。

编辑:当然,你不能以你提供的方式使用@Around - 但是这个主题已经被另一个答案解决了,所以这里省略了。

edit2:如果您需要有关如何获得spring托管bean的帮助,请随时询问。但既然你已经设置了方面bean,我相信你可以处理这个:)

编辑3:呵呵。好吧..也许不是:)。

ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

将加载您的应用程序上下文。 通过调用:

从那里加载bean
TestableBean testableBean = (TestableBean )ctx.getBean("testableBean ");

定义TestableBean,就像使用Aspect bean一样。

edit4:现在我很确定故障是非弹簧托管bean。

Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as there is no requirement to introduce the AspectJ compiler / weaver into your development and build processes. If you only need to advise the execution of operations on Spring beans, then Spring AOP is the right choice. If you need to advise domain objects, or any other object not managed by the Spring container, then you will need to use AspectJ.

取自:http://static.springsource.org/spring/docs/2.0.x/reference/aop.html