views:

468

answers:

5

My team is moving to Spring 3.0 and there are some people who want to start moving everything into Annotations. I just get a really bad feeling in my gut (code smell?) when I see a class that has methods like this: (just an example - not all real annotations)

@Transaction
@Method("GET")
@PathElement("time")
@PathElement("date")
@Autowired
@Secure("ROLE_ADMIN")
public void manage(@Qualifier('time')int time) {
...
}

Am I just behind the times, or does this all seem like a horrible idea to anyone else? Rather then using OO concepts like inheritance and polymorphism everything is now by convention or through annotations. I just don't like it. Having to recompile all the code to change things that IMO are configuration seems wrong. But it seems to be the way everything (especially Spring) is going. Should I just "get over it" or should I push back and try to keep our code as annotation free as possible?

+9  A: 

Actually I think that the bad feeling in your gut against has more to do with Annotations like this mixing configuration with code.

Personally I feel the same way as you do, I would prefer to leave configuration (such as transaction definitions, path elements, URLs that a controller should be mapped to, etc.) outside of the code base itself and in external Spring XML context files.

I think though that the correct approach here though comes down to opinion and which method you prefer - I would predict that half the community would agree with the annotations approach and the other half would agree with the external configuration approach.

matt b
See I've found, at my work, that the programmers I generally see as the "better" programmers really dislike annotations - but the others are al about them. Now since these guys think like me, tat's probably why I see them as "better" programmers.
Gandalf
Annotations aren't bad. JPAs use of them is fabulous in my opinion. But there's a time and a place for everything, and if you have more than two lines worth, you're probably doing something wrong.
Chris Kaminski
I think everyone sees people that think like them as the "better" people :)
matt b
@matt b - yeah that's why I mentioned the correlation :)
Gandalf
I agree with not mixing configuration with code. Also, you are coupling the code with a specific IOC implementation. For instance, if you were to decide to change from Spring to Guice (unlikely given its a big change, but it could happen), then you would have to change all of your code instead of just the configuration
Richard
+3  A: 

Check these answers to similar questions

What are the Pros/Cons of Annotations (non-compiler) compared to xml config files

Xml configuration versus Annotation based configuration

Basically it boils down to: Use both. Both of them have there usecases. Don't use annotations for things which should remain configurable without recompiling everything (especially things which maybe your user should be able to configure without needing you to recompile all)

jitter
the only thing is example that might be configurable is @Secure("ROLE_ADMIN"), however knowing xml junkies they would even put @Method("GET") in xml.
01
+3  A: 

I was also initially skeptical about annotations, but seeing them in use, they can be a great thing. They can also be over used.

The main thing to remember about annotations is that they are static. They cannot change at runtime. Any other configuration method (xml, self-description in code, whatever) does not suffer from this. I have seen people here on SO have issues with Spring in terms of having a test environment on injecting test configurations, and having to drop down to XML to get it done.

XML isn't polymorphic, inherited or anything else either, so it is not a step backwards in that sense.

The advantage of annotations is that it can give you more static checking on your configuration and can avoid a lot of verbosity and coordination difficulties in the XML configurations (basically keeping things DRY).

Just like XML was, Annotations can be over used. The main point is to balance the needs and advantages of each. Annotations, to the degree that they give you less verbose and DRYer code, are a tool to be leveraged.

EDIT: Regarding the comment about an annotation replacing an interface or abstract class, I think that can be reasonable at the framework boundary. In a framework intended to be used by hundreds, if not thousands of projects, having an interface or base class can really crimp things (especially a base class, although if you can do it with annotations, there is no reason you couldn't do it with a regular interface.

Consider JUnit4. Before, you had to extends a base class that had a setup and tear down method. For my point, it doesn't really matter if those had been on an interface or in a base class. Now I have a completely separate project with its own inheritance hierarchy, and they all have to honor this method. First of all, they can't have their own conflicting method names (not a big deal in a testing framework, but you get my point). Second of all you have have the chain of calling super all the way down, because all methods must be coupled.

Now with JUnit4, you can have different @Before methods in different classes in the hierarchy and they can be independent of each other. There is no equally DRY way to accomplish this without annotations.

From the point of view of the developers of JUnit, it is a disaster. Much better to have a defined type that you can call setUp and teardown on. But a framework doesn't exist for the convenience of the framework developer, it exists for the convenience of the framework user.

All of this applies if your code doesn't need to care about the type (that is, in your example, nothing would every really use a Controller type anyway). Then you could even say that implementing the framework's interface is more leaky than putting on an annotation.

If, however, you are going to be writing code to read that annotation in your own project, run far away.

Yishai
My bigger issue isn't even with the configuration side, but using things like @Controller rather then having an interface/abstract class called `Controller` and then extending/implementing it really screams bad design to me. Why even use an OO language if you're going to ignore it?
Gandalf
+1  A: 

I personally feel that annotations have taken over too much and have blown up from their original and super useful purpose (e.g., minor things like indicating overridden method) into this crazy metaprogramming tool. I don't feel the JAva mechanism is robust enough to handle these clusters of annotations preceding each method. For instance, I'm fighting with JUnit annotations these days because they restrict me in ways that I don't like

That being said, in my experience the XML based configuration isn't pretty either. So to quote South Park, you're choosing between a giant douche and a t*rd sandwich.

I think that the main decision you have to make is whether you are more comfortable with having a delocalization of the spring configuration (i.e., maintain two files instead of one), and whether you use tools or IDE plugins that benefit from the annotations. Another important question is whether the developers who will use or maintain your code truly understand annotations.

Uri
The only thing that makes XML configuration files not totally painful is the support of IDEs. Without IDE support, no type safety, no refactoring, etc and with all these strings, that would just be a nightmare. No, really, I don't find XML ideal. But you are right, annotations are not ideal too, at least not for everything.
Pascal Thivent
@Pascal: I've mostly used Hibernate, not Spring, and I found the XML version to be a significant pain, with the annotations being a little easier as long as I only used a precious few. My impression from Spring is that the potential for crazy constructs that nobody understands is higher...
Uri
@Uri That's absolutely true. XML hell...
Pascal Thivent
+5  A: 

Maybe you have a problem with redundant annotations that are all over the code. With meta-annotations redundant annotations can be replaced and your annotations are at least DRY.

From the Spring Blog:

@Service
@Scope("request")
@Transactional(rollbackFor=Exception.class)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyService {
}

@MyService
public class RewardsService {
…
}

Because Java evolves so slowly people are putting more features that are missing in the language into annotations. This is a good thing Java can be extended in some form and this is a bad thing as most of the annotations are some workaround and add complexity.

Thomas Jung
I think I like that even less.
Gandalf
The problem here is that lots of people can't tell what should be in a programming language as opposed to a runtime library. Giving them the idea they can "extend" the language via annotations creates more problems than are solved imho.
rsp
There is no correct answer to this question. Take the @Transactional annotation, if it were not possible to annotate your type you would have XML configuration or an even more powerful solution with AOP. So this one is definitely positive.
Thomas Jung
Why? Why is this solution any better then XML or AOP? With XML I can change the transaction settings without recompiling - with this solution you can't. And there are many ways to do transactions that don't involve any of the three - programmatic handling of transactions isn't that hard.
Gandalf
Why would you be interested in changing the transaction settings without compiling, when surely you will have to run such a change through a QA build/deploy/test cycle anyway?
Steven Huwig
XML: Multiple places to look at to get the full picture. Ideally, everything you have to know to solve the problem at hand would fit on one page. If you do not need a configuration it adds only complexity. AOP: AOP is very powerful. It adds on the other hand complexity (additional concepts, new language, complex runtime behavior). If you replace @Transaction proxies with AOP you're replacing a quite complex technology with another even more complex technology.
Thomas Jung
Umm, your very example puts the configuration in multiple places - how is it different then multiple XML files?
Gandalf
You are right it is in multiple places. So the spring meta annotation is not an ideal solution. It's a trade-off between redundancy and complexity. It has the advantage that it is in one format and supported by Java tools. (In theory meta annotation tool support could explode the definition. It would be in one place again. This is trivial to implement.)
Thomas Jung