Spring AOP:建议未触发
尝试设计简单的方面,当执行任何公共方法时,将打印单词“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 的理解正确吗?
Trying to design simple aspect,that will print word "logg" to console,when any of public methods executed.
aspect:
@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"/>
simple bean:
package aspectlogging;
@Component
public class TestableBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
test:
public class TestLogging {
public static void main(String[] args) {
TestableBean tb = new TestableBean();
tb.setName("yes");
tb.getName();
}
}
I expect,that result of running of TestLogging
will be "logg" word in console,and no output returned.
Do I understand AOP correctly in this case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
对于
@Around
建议,您需要为建议方法提供一个ProceedingJoinPoint pjp
参数,并在该点调用pjp.proceed()
当您希望调用包装方法时的顾问程序。当您所做的事情可以正常工作时,使用 @Before 建议确实更容易。[编辑]:此外,您必须让 Spring 为您构建 bean,而不是直接调用
new
。这是因为 bean 对象实际上是真实对象(位于其中)的代理。由于您的目标对象没有实现接口,因此除了 Spring 库之外,您还需要在类路径中添加 cglib 库。 (或者,您可以完全使用 AspectJ,但这需要使用不同的编译器配置。)要创建 bean,您首先需要创建一个 Spring 上下文,然后在其中查询 bean 实例。这意味着您从: 更改为
(假设您使用的是 Spring 3,并且您的 XML 配置位于类路径上的“config.xml”中):
其余代码保持不变(在调整
import 后)
语句和可能的附加依赖项)。With
@Around
advice, you need to have aProceedingJoinPoint pjp
argument to the advising method and to callpjp.proceed()
at the point in the advisor when you want the wrapped method to be called. It's easier to use@Before
advice really, when what you've done will otherwise work just fine.[EDIT]: Also, you must let Spring construct your beans for you instead of directly calling
new
. This is because the bean object is actually a proxy for your real object (which sits inside it). Because your target object doesn't implement an interface, you will need to have the cglib library on your classpath in addition to the Spring libraries. (Alternatively, you can go with using AspectJ fully, but that requires using a different compiler configuration.)To create your beans, you first need to create a Spring context and then query that for the bean instance. This means you change from:
To (assuming you're using Spring 3, and that your XML config is in "config.xml" somewhere on your classpath):
The rest of your code remains the same (after adjusting for
import
statements and possibly additional dependencies).对此不太确定,但也许您需要使用 Spring 管理的 TestableBean 来让 Spring AOP 接收方法调用。
编辑:当然,您不能按照您提供的方式使用
@Around
- 但这个主题已由另一个答案解决,因此此处省略。edit2:如果您需要有关如何获取 Spring 托管 bean 的帮助,请随时询问。但既然你已经设置了方面 bean,我相信你可以处理这个:)
edit3:呵呵。好吧..也许不会:)
将加载您的应用程序上下文。
通过调用从那里加载 bean:
定义
TestableBean
就像您对 Aspect bean 所做的那样。edit4:现在我很确定错误是非Spring管理的bean。
使用最简单、可行的方法。 Spring AOP 比使用完整的 AspectJ 更简单,因为不需要将 AspectJ 编译器/编织器引入到您的开发和构建过程中。如果您只需要建议在 Spring bean 上执行操作,那么 Spring AOP 是正确的选择。如果您需要建议域对象或任何其他不受 Spring 容器管理的对象,那么您将需要使用 AspectJ。
摘自:http://static.springsource.org/spring/docs/2.0.x/reference/aop.html
Not quite sure on this one, but maybe you need to use a spring managed TestableBean to have spring AOP pick up the method call.
edit: of course, you can't use
@Around
the way that you provided - but this subject has been addressed by another answer, so it's omitted here.edit2: If you need help on how to get a spring managed bean, please feel free to ask. but since you already got your aspect bean set up, I believe you can handle this :)
edit3: Hehe. Ok.. maybe not :)
will load your application context.
Load beans from there by calling:
Define the
TestableBean
just like you did with your Aspect bean.edit4: Now I'm pretty sure that the fault is the non-spring managed 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.
Taken from: http://static.springsource.org/spring/docs/2.0.x/reference/aop.html