| Author |
Aspectj and Spring - adding methods
|
Rusty Enisin
Ranch Hand
Joined: May 26, 2005
Posts: 107
|
|
In spring if you want to have access to the ApplicationContext in a bean make the bean implement the ApplicationContextAware interface. Cool. I did not want to hand edit all my beans. This would be much better if I could use AspectJ to add the interface, required methods and instance vairables. So I did. Now I have a problem. How do I use the instance variables and/or methods I added? I can't do it from within the class' original code because at that time the additional interface stuff does not exist, it will not compile. I would like to access an instance variable from within the aspect's before() advice. Something like this: Is there a way to access the target class' methods and/or variables?
|
The squeaky wheel gets the grease. Well, that or replaced...
|
 |
Rusty Enisin
Ranch Hand
Joined: May 26, 2005
Posts: 107
|
|
This was both easier and harder than I thought it would be. First all you need to do to get the target is call thisJoinPoint.getTarget() and cast it to whatever it is. Now the harder part was adding an interface and class variable to multiple classes that match a pattern. This was the only way I could guarantee each class that matches the pattern could be acessed with genetic code. In order to add methods and variables to a class you need to have a marker interface. In the following code snippet I have two interfaces that are real that require methods. I define the other method within the aspect. Declare the required methods of the real interfaces (ApplicationContextAware, ApplicationContextRetrievable) using the local marker interface (Auditable). The context setter method is required for ApplicationContextAware. I needed a getter method too. So I created the ApplicationContextRetriever interface for that. You have to do it this way bacause AspectJ does not allow you to add a single method or variable to a class pattern with wild characters. You have to use the interface. And you cannot use external interfaces to add. So use an internal marker interface to add actual methods for real interfaces. Seems odd. But that is how it is. What this code does is, to all the methods that match the pattern com.mycomp.*.*(..), adds the ApplicationContextAware interface , a class variable context, and setter/getter methods for the context variable. Here comes the magic. Now that the classes are ApplicationContextAware, Spring will automatically call the setter when it loads the bean and then the before() advise will be able to call the getter. Now you have access to each bean's ApplicationContext without having to tie each bean to Spring in its code.
|
 |
 |
|
|
subject: Aspectj and Spring - adding methods
|
|
|