http://jroller.com/comments/colyer/Weblog/what_the_teacher_said_using<!--StartFragment -->
Yesterday I introduced a simple example of a Teacher
aspect responding to a playground kiss. Today's objective is to make the teacher's response configurable as a bean property using Spring.
First let's update the Teacher
aspect to have a response
property. I'm going to use setter-injection for reasons that will become apparent later:
public aspect Teacher {
private String response;
public void setResponse(String response) { this.response = response; }
/**
* There are many things that can be kissed, and many possible kissers,
* but here we're just interested in Girls kissing Boys.
*/
pointcut aGirlKissingABoy() : call(* Kissable.kiss()) && this(Girl) && target(Boy);
/**
* Now we get to decide what the teacher's reaction is to the kiss...
*/
after() returning : aGirlKissingABoy() {
System.out.println(response);
}
}
Now the tricky bit - how do we convince Spring to configure the Teacher aspect? Spring usually both instantiates and configures bean objects, but aspects in AspectJ are implicitly constructed on point of first reference - so it doesn't work for Spring to simply call the default constructor of Teacher
. This is also the reason that we can't use constructor-injection: AspectJ will actually give a compile-time error if you attempt to define a non-zero argument constructor in an aspect. I've played round with various permutations to address this configuration problem, and I don't claim to have arrived at the ideal solution yet, but the following works quite nicely.
<beans>
<bean id="girl" class="Girl">
<property name="kissable"><ref bean="boy"/></property>
</bean>
<bean id="boy" class="Boy">
</bean>
<bean id="teacher" class="Teacher" factoryMethod="aspectOf">
<property name="response"><value>we'll have none of that please...</value></property>
</bean>
<bean id="aspectFactory" class="org.aspectj.springframework.beans.factory.config.AspectBootstrapBean">
<property name="aspects">
<list>
<ref bean="teacher"/>
</list>
</property>
</bean>
</beans>
Notice that the teacher
bean is configured almost exactly like any other bean, except that instead of letting Spring use a default constructor to create an instance of the bean, we ask it to use a factory method instead. In this case the factory method is aspectOf
, which is defined by AspectJ on every singleton aspect and returns the aspect instance as created by the AspectJ runtime. I added an second bean into the mix too, the "aspectFactory
" bean. Note that the class of this bean refers to a framework class I wrote to aid in the bootstrap process. This bean is configured like any other bean, and has an "aspects
" property that should be passed a list of all the (aspect) beans to be used in the program. This has the consequence that loading the aspectFactory
bean causes Spring to create and configure all of the aspects we will need.
Here's the updated main program that puts it all together:
public class Main {
public static void main(String[] args) throws Exception {
XmlBeanFactory beanFactory = new XmlBeanFactory(new FileInputStream("beans.xml"));
beanFactory.getBean("aspectFactory"); // causes init and config of all aspects
Girl g = (Girl) beanFactory.getBean("girl");
g.kiss();
}
}
If you run this program you get the output:
wahay!
we'll have none of that please...
confirming that Spring has indeed configured the teacher
aspect correctly. Aspects configured in this way support all of the various property types that Spring offers (references to other beans, lists, maps, constant values, etc.).
There's lots more to talk about - in future posts I'll discuss what happens when you want two Teachers to show up at the same time, the issues surrounding aspect instantiation models other than the default (perthis, pertarget, ...), how to (dynamically) configure pointcut expressions as bean properties, using the Spring configuration to enable and disable aspects, and of course how AspectJ fits in with Spring's own AOP framework.
All of this is new territory, so if you've suggestions for how you'd like to see things work, just let me know...
Ok, I confess, I cheated a little bit. The "factoryMethod
" attribute doesn't yet exist in Spring's DTD, but I've been talking a lot with Rod Johnson about all this and it will be coming in the Spring 1.0.3 release. Until then, there's a variation you can use that works with Spring today, but is a little more verbose. It entails a change to the config file I showed you, and it looks like this:
<beans>
<bean id="girl" class="Girl">
<property name="kissable"><ref bean="boy"/></property>
</bean>
<bean id="boy" class="Boy">
</bean>
<bean id="teacher" class="org.aspectj.springframework.beans.factory.config.AspectFactoryBean">
<property name="staticMethod"><value>amc.Teacher.aspectOf</value></property>
<property name="aspectProperties">
<map>
<entry key="response">
<value>we'll have less of that please...</value>
</entry>
</map>
</property>
</bean>
<bean id="aspectFactory" class="org.aspectj.springframework.beans.factory.config.AspectBootstrapBean">
<property name="aspects">
<list>
<ref bean="teacher"/>
</list>
</property>
</bean>
</beans>
For the curious, AspectFactoryBean
is a little helper class I wrote that extends Spring's MethodInvokingFactoryBean
to also configure the bean that it creates.
分享到:
相关推荐
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
java错误-java.lang.ClassNotFoundException: org.aspectj.lang.annotation.Around Spring的AOP需要上述三个jar包
com.springsource.org.aspectj.weaver-1.6.8.jar
aspectj.weaver最新的185版本
com.springsource.org.aspectj.tools-1.6.6.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
3.5.2. Wiring with the Spring Expression Language 3.6. Summary Chapter 4. Aspect-oriented Spring 4.1. What is aspect-oriented programming? 4.1.1. Defining AOP terminology 4.1.2. Spring’s AOP support ...
Manning.AspectJ.in.Action.2nd.Edition.Sep.2009.eBook-BBL 书名:AspectJ.in.Action.2nd.Edition《AspectJ实战第2版》 作者: Ramnivas Laddad, Rod Johnson 出版商:Manning. 发行日期:2009年9月28日 ISBN:...
java spring4.0以上版本 aop 需要依赖的类包 om.springsource.org.aspectj.weaver-1.7.2.RELEASE.jar
aspectj-1.9.6-src.jar
aspectj-1.8.14-src.jar
这是面向切面所需的三个jar包,导入即可使用aspectj使用的官网最新版本:aspectj-1.8.6.jar。 aspectj-1.8.6.jar来自官网下载 aspectjrt.jar和aspectjweaver.jar下载自网络 皆非本人创作
aspectj.weaver 和 aspectj.tools 类包 Spring 4.X 使用@AspectJ和Schema 报错,添加aspectj.weaver 和 aspectj.tools 类包的依赖。
aspectj-1.9.6.jar.7z
spring aspectj aspectrt.jar
org.aspectj,aspectj项目库(org.aspectj).zip,建筑物
包括:com.springsource.net.sf.cglib-2.2.0.jar、com.springsource.org.aopalliance-1.0.0.jar、com.springsource.org.aspectj.weaver-1.6.4.RELEASE.jar、commons-logging-1.1.1.jar、spring-aop-5.2.6.RELEASE....
标签:aspectj-1.6.5.jar.zip,aspectj,1.6.5,jar.zip包下载,依赖包