This week's book giveaway is in the Programmer Certification forum.
We're giving away four copies of OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815 and have Jeanne Boyarsky & Scott Selikoff on-line!
See this thread for details.
Win a copy of OCP Oracle Certified Professional Java SE 11 Programmer I Study Guide: Exam 1Z0-815 this week in the Programmer Certification forum!
  • 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 all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Junilu Lacar
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Knute Snortum
  • Devaka Cooray
  • Tim Cooke
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Ron McLeod
  • Carey Brown
Bartenders:
  • Paweł Baczyński
  • Piet Souris
  • Vijitha Kumara

Aspectj and Spring - adding methods

 
Ranch Hand
Posts: 107
  • Mark post as helpful
  • send pies
  • 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
  • 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.
 
Oh the stink of it! Smell my tiny ad!
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!