• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Aspectj and Spring - adding methods

 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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?
 
Rusty Enisin
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic