What the teacher said (using AspectJ with Spring part II).
来源:互联网 发布:网络舆论是不完善的 编辑:程序博客网 时间:2024/05/16 07:23
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.
- What the teacher said (using AspectJ with Spring part II).
- 对收藏夹中AspectJ和Spring结合使用例子(What the teacher said (using AspectJ with Spring part II). )的补充
- Using the Input Subsystem, Part II
- Using the Input Subsystem, Part II
- Using the Input Subsystem, Part II
- Using the Input Subsystem, Part II
- Part II. What’s New in Spring Framework 4.x
- spring mvc with aspectJ
- playing with dacapo using aspectj [the series about program instrumentation is done]
- The Login Page: Angular JS and Spring Security Part II
- "The Trouble with Checked Exceptions A Conversation with Anders Hejlsberg, Part II" 阅读笔记
- Playing with ptrace, Part II
- Playing with ptrace, Part II
- Playing with ptrace, Part II
- Playing with ptrace, Part II
- Playing with ptrace, Part II
- Playing with ptrace, Part II
- LINQ to SQL系列Part 9-Using a Custom LINQ Expression with the control
- linux下各种后缀名解压
- 我发布的第一个java作品:Sogou file uploader
- 取當前日期各种數据庫的寫法
- 怎么给这个xml文件建立对象,以便使对象和xml文件序列化和反序列化
- UseCase(用例)的本质
- What the teacher said (using AspectJ with Spring part II).
- 我真的感觉不到你
- 广州网络接入
- 对收藏夹中AspectJ和Spring结合使用例子(What the teacher said (using AspectJ with Spring part II). )的补充
- 编程提交表单
- 枚举类型入门(转载自IBM开发者)
- 用Split劈开一个字符串
- 实例解析 IPv6下的VC网络编程
- 指针与引用的区别