尝试设计简单的方面,当执行任何公共(public)方法时,将打印单词“logg”到控制台。
方面:
@Aspect
public class LoggingAspect {
@Pointcut("execution(public * *(..))")
public void publicServices() {
};
@Before("publicServices()")
public void logg() {
System.out.println("logg");
}
}
xml 配置:
<context:component-scan base-package="aspectlogging" />
<aop:aspectj-autoproxy/>
<bean id="loggingAspectHolder" class="aspectlogging.LoggingAspect"/>
简单的bean:
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 的理解正确吗?
最佳答案
对于 @Around
建议,您需要为建议方法提供一个 ProceedingJoinPoint pjp
参数,并在以下位置调用 pjp.proceed()
当您希望调用包装方法时顾问程序中的点。当您所做的事情本来可以正常工作时,使用 @Before
建议确实更容易。
[编辑]:此外,您必须让 Spring 为您构建 bean,而不是直接调用 new
。这是因为 bean 对象实际上是真实对象(位于其中)的代理。由于您的目标对象没有实现接口(interface),因此除了 Spring 库之外,您还需要在类路径中添加 cglib 库。 (或者,您可以完全使用 AspectJ,但这需要使用不同的编译器配置。)
要创建 bean,您首先需要创建一个 Spring 上下文,然后在其中查询 bean 实例。这意味着您从以下位置更改:
TestableBean tb = new TestableBean();
至(假设您使用的是 Spring 3,并且您的 XML 配置位于类路径上的“config.xml”中):
ApplicationContext context = new ClassPathXmlApplicationContext("config.xml");
TestableBean tb = context.getBean(TestableBean.class);
代码的其余部分保持不变(在调整 import
语句和可能的其他依赖项之后)。
关于 Spring AOP : advice is not triggered,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7742283/