Thursday, December 13, 2007

Annotations and Spring

At the Spring Experience, in several different sessions, there is quite a bit of coverage of different uses of annotations. I may have to update my list.

One of the really interesting uses (maybe I'm just ignorant here) is to identify classes and methods to apply point cuts with AOP. This seems like the perfect use of meta-data. This one isn't necessarily a Spring thing, just cool.

The use of annotations in the MVC project have some good and bad. One good thing is the use of an annotation to identify a controller, rather than having the controller extend the AbstractController. This means the class doesn't need to depend upon Spring classes. This should help preserve backward dependability (to your app) as the framework evolves.

Another cool thing is the ability to decide which method gets called by the value of a request parameter, via annotation. This changes to a more declarative model of programming that should make code easier to develop and much easier to test (less logic, less to test).
@RequestMapping(params = "action=delete")
public void removeSite(@RequestParam("site") String site,
&nbp;&nbp;&nbp;ActionResponse response) {
.


Then there is a scary part, using annotations to map URL patterns to controllers. This means the URL patterns will get scattered around the code base (hopefully in only one or two packages). The XML configuration isn't perfect but, personally, I'd like to see URL mappings in one place.
@RequestMapping("/myAction.do")
public void handleAction....


An interesting thing of the how annotations are used in Spring is in many places they help remove dependence on Spring classes and interfaces. "Use Spring but, don't depend on it".

@PostContruct and @PreDestroy (function are obvious from the name) are pretty cool.
@Resource both powerful AND dangerous (this one is for annotation driven dependency injection). Using this could make unit test more challenging.
@Autowired is a good way to reduce XML if auot wired beans don't scare you.


A little validation for my attitude with annotations. During Rod Johnson's presentation on The State of the Art Dependency Injection, he said that he like annotations but, not annotations that take strings (even the stuff in Spring). At least if I'm crazy, I'm not alone
:-)

Update: reference to this post on DZone
.
.
.

Labels: , , , , ,

permalink
Links to this post

8 Comments:

At 14 December, 2007 09:23, Blogger Solomon said...

You're definitely not alone about annotations. Perhaps convention-over-configuration can help here... Or at least more generic annotations can be used for the MVC processing.

Don't be too scared of the use of thw @Autowire word specifically. It has a vary different connotation than the classical Spring definition of autowiring. It's meaning is very similar to @Resource. The meaning is basically "I need something of type [blah]" and nothing more.

The danger of @Resource as far as testing is concerned is (or @Autowired for that matter) is when the annotation is applied to a member variable.

@Autowired can and should be applied to setters, constructors and other random "factory" methods that are public or otherwise accessible by a test (for example, package-level access).

If you can, please contact me offline... I have a colleague at TSE that will buy you a beer ;)

I'm also trying to figure out some good fixes for the deficiencies that you're mentioning, and would like to discuss it with you...

 
At 14 December, 2007 12:55, Anonymous Anonymous said...

I detest @PostContruct and @PreDestroy. They are kind of okay as long as the method takes no parameters. As soon as you need a parameter (e.g. a context object or event object) you've got your dependency again. BTW what happens if you provide two @PreDestroy methods, what if the method has a return type or takes a parameter? Was the programmer clever enough to implement checks for all cases and is the error message clear enough? What about overriding the init method?

I really prefer interfaces for callbacks because they provide compile time and make the dependency (which exists anyway) explicit.

Yours,
Stefan

 
At 14 December, 2007 14:58, Blogger willCode4Beer said...

Hi Stefan, I hadn't thought of it like that. You make an excellent point.
I was beginning to think along the lines of annotations effectively replacing interfaces in some places. But, you comment shows there is a big potential for danger there.

BTW, are you at the TSE?

 
At 14 December, 2007 16:06, Blogger Solomon said...

IMHO, you're going to see plenty of examples in the near future that have similar characteristics as @PostContruct and @PreDestroy.

Those specific annotations have a "singletonness" about them that needs to be validated at some early point in time. Perhaps that could be a addition to the Java Spec to have compile-time checking for those types of scenarios.

The new Spring MVC and other annotation based frameworks will use the same technique of annotations+random parameters to do some slick things.

For example, a dao framework can automatically determine how to implement how the following:

@Dao
public interface UserDao{

@Query List findUserById(Number id);

}

 
At 15 December, 2007 15:59, Blogger Dmitry Sklyut said...

As to your concern about url mapping in code: XML config will always take precedence over all other meta-data. Rod said as much during his DI talk at TSE. Plus all of the annotations are side effect free. You can still keep them in the code and fully switch to XML if you so desire at a later date.

 
At 15 December, 2007 19:37, Blogger Dan B said...

The good thing about using annotations to map URL patterns to controllers is that, when you are looking at a controller, you can easily see what URL invokes it. For the reverse situation, when you have a URL and want to find the controller that is invoked, a project-wide text search will locate it easily enough.

 
At 16 December, 2007 21:54, Anonymous josh k said...

And to top off from what dan b and Dmitry Sklyut have said, you can also mix and match, using a combination of xml for your basic form controllers and annotations for your multiaction controllers, which will have request mapping annotations above each method. I have tried this out at home and quite like how it work and give a two thumbs up for the new improvements.

 
At 19 December, 2007 04:51, Anonymous Anonymous said...

Hi about @PostContruct and
@PreDestroy, actually I really like the way they are designed.
They are simple and easy to use and replace in a good way the XML init-method and the XML destroy-method ones. Those XML methods do not allowed multi argument either.
If you need arguments, why don't you inject them in your bean and then wrap the method in a non-argument one?
If you don't really care of the order of execution, you can also execute the init method using a @Autowired on it as far as it supports multiarguments.
Do you have any cases that prevent those patterns?

Olivier

 

Post a Comment

Subscribe to Post Comments [Atom]

<< Home

Links to this post on:

Create link here by posting on Blogger