• Post Reply Bookmark Topic Watch Topic
  • New Topic

Developing rich annotations  RSS feed

 
Jeffrey Coleman
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am trying to develop annotations that will assist me in eliminating a lot of repeated code such as logging and auditing.

So far I've only seen how to make an annotation that will allow for values to be put in. When you annotate a pojo with @EJB it gets all this functionallity or in struts when you use the @Conversion() annotation and the @TypeConversion annotation they DO something for you. In an EJB you can even use annotations to specify methods to run before and after the methods or EJBs you call

How does this work?
How can I make annotations that inject code into the classes and methods that I annotate with my custom annotations?
Can I have a short little functional example? (Maybe just a annotation that maks a method print a method's parameters? Or a class annotation that prints a list of methods?)
How are things like @BeforeInvoke and @AfterInvoke coded?
When a class or method is annotated, what does that look like in memory? Is there a copy of the annotation with the class or does is live somewhere else seperate?

I know that's a lot but google keeps on comming up with nothing but this



and no clear explaination of how to make it useful.

Any guidence would be appreciated.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
What you are suggesting is not the common use-case for Annotations. Think of annotations as markers. That is pretty much all they do - they mark things so that other things know about them. So there is nothing you can add to the Annotation definition to make it do something.

What you would have to do is write an annotation Processor. The annotation processor finds all the annotations you add to the source code and does something with them. Annotation Processors are typically run at compile time, but can be run at run time using reflection when the class is loaded (given a custom ClassLoader); they won't help you when a method is called. To do what you want - for example logging the input parameters on a method - is not an easy task. It probably requires injecting code into the method during annotation processing, or wrapping a method call in another method call.

What you really want (I think) is AspectJ, or another Aspect Oriented Programming framework.
 
Jayesh A Lalwani
Rancher
Posts: 2762
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am assuming you are talking about runtime code injection, and not compile time. For runtime code injection you need to use a framework that does injection of code (like AOP, or Spring which internally uses AOP) or you need to build your own mechanism

The basic idea behind injecting code is that you create a proxy class. Let me take Spring as an example. Basically, what happens behind the scenes Spring creates a proxy class at runtime that delegates to the real object

So, let's say you have an interface for a service that gets list of users and you have an implementation of the class, and a class that uses the implmentation via the interface



Now, in an application that uses Spring, Spring injects the userService into UserController. If the service is annotatted, behind the scenes, SPring creates a class at runtime that implements Userservice and delegates to the real UserService. The class looks somewhat like this



Now, when Spring gives a userService to UserController, it gives an instance of LoggingUserServiceProxy. COntroller doesn't know that.. When controller calls getUser.. the control goes to the proxy, the proxy logs before the method, then calls the real getUsermethod, and then does some more logging

Ok, so what do you do if you are not using Spring? It depends on whether you are doing your dependency injection, or if you have factory methods. Java provides a class called Proxy that helps create runtime proxy classes like the one above. Look at the link. It has details. It becomes easy to plug this in your code if you the code that creates objects is centralized (like if you are using Dependency Injection pattern, or factory pattern, or ServiceLocator pattern). Basically, the code that is responsible for instantiating objects, can inspect the object that it has created to check if it is annotated. If it is annotated, it can create the Proxy and return the proxy. Boom! you sort of implemented your own bare bones AOP.

If your object creation code is not centralized, you are out of luck.
 
Jeffrey Coleman
Greenhorn
Posts: 23
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well that wasn't exactly what I thought I was going to get but it's good stuff to know. The app I was trying to use this for is already too far along for me to try to do all this and work it in. I'm still going to read into AOP and DI patterns. Can you recommend any books?
 
Jayesh A Lalwani
Rancher
Posts: 2762
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Don't know if there are books just on runtime annotation processing. I learnt about parodying while I was studying spring, and by just generally reading java docs. Here's spring aop in depth if it helps you
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!