Spring AOP:未触发通知
试图设计一个简单的方面,当执行任何公共方法时,它会将单词“logg”打印到控制台 方面:Spring AOP:未触发通知,spring,aop,spring-aop,Spring,Aop,Spring Aop,试图设计一个简单的方面,当执行任何公共方法时,它会将单词“logg”打印到控制台 方面: @Aspect public class LoggingAspect { @Pointcut("execution(public * *(..))") public void publicServices() { }; @Before("publicServices()") public void logg() { System.out.print
@Aspect
public class LoggingAspect {
@Pointcut("execution(public * *(..))")
public void publicServices() {
};
@Before("publicServices()")
public void logg() {
System.out.println("logg");
}
}
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();
}
}
xml配置: <context:component-scan base-package="aspectlogging" />
<aop:aspectj-autoproxy/>
<bean id="loggingAspectHolder" class="aspectlogging.LoggingAspect"/>
测试:@Aspect
public class LoggingAspect {
@Pointcut("execution(public * *(..))")
public void publicServices() {
};
@Before("publicServices()")
public void logg() {
System.out.println("logg");
}
}
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
参数,并在希望调用包装的方法时在advisor中的点调用pjp.procedure()
。在建议之前使用@会更容易,实际上,当你所做的一切都可以正常工作时
[编辑]:此外,您必须让Spring为您构建bean,而不是直接调用
new
。这是因为bean对象实际上是真实对象(位于其中)的代理。因为您的目标对象没有实现接口,所以除了Spring库之外,您还需要在类路径上有cglib库。(或者,您可以完全使用AspectJ,但这需要使用不同的编译器配置。)
要创建bean,首先需要创建一个Spring上下文,然后为bean实例查询该上下文。这意味着您将从以下位置更改:
TestableBean tb = new TestableBean();
到(假设您使用的是Spring3,并且您的XML配置位于类路径上的某个“config.XML”中):
代码的其余部分保持不变(在调整了
import
语句和可能的附加依赖项之后)。对此不太确定,但可能需要使用spring管理的TestableBean让spring AOP拾取方法调用
编辑:当然,你不能像你提供的那样使用@Around
——但是这个问题已经被另一个答案解决了,所以这里省略了
edit2:如果您需要关于如何获得spring管理的bean的帮助,请随时询问。但既然您已经设置了aspect bean,我相信您可以处理这个问题:)
编辑3:呵呵。好啊也许不是:)
将加载应用程序上下文。
通过调用以下命令从那里加载bean:
TestableBean testableBean = (TestableBean )ctx.getBean("testableBean ");
定义TestableBean
,就像使用方面bean一样
edit4:现在我很确定错误在于非spring管理的bean
使用最简单的方法。SpringAOP比使用完整的AspectJ更简单,因为不需要在开发和构建过程中引入AspectJ编译器/weaver。如果您只需要建议在SpringBean上执行操作,那么SpringAOP是正确的选择。如果您需要通知域对象或任何其他不由Spring容器管理的对象,则需要使用AspectJ。
摘自:您的意思是,我应该在xml配置中指定TestableBean,还是将其声明为@Service?恐怕它不灵活,就我而言,我的特性将被许多类使用。请先试用一下。如果这是解决方案,我们可以找到一种方法,使其更“灵活”。有很多不同的方法可以让spring捡拾你的豆子。例如:是的,我从上下文中了解bean。问题是我是否将此方面用作库,外部项目希望插入它,因此他们需要在配置中指定所有bean?我将此AOP视为侦听器,侦听任何公共方法,并在返回值时记录一些结果。请参阅我的edit4。不可能在非Spring管理的bean上使用Spring AOP。使用完整的aspectj;我刚注意到房间里的大象。让春天来做豆子,让它为你编织它的魔力;Donal,你的意思是我不需要从上下文手动调用getBean()?@sergionni:我的意思是,不要做“新建Blah()
,做context.getBean(Blah.class)`。您不使用Spring直接构建对象,而是使用Spring作为您的对象工厂(假设您希望这些对象是bean;非bean可以以任何方式生成)。