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
Annotations are plain bad in my experience:
If Java would have something like "method literals" you could annotate a class in a corresponding annotation class. Something like as following: Take for instance javax.persistence, and the following annotated class:
@Entity
class Person
{
@Column
private String firstname;
public String getFirstname() { return firstname; }
public void setFirstname(String value) { firstname = value; }
@Column
private String surname;
public String getSurname() { return surname; }
public void setSurname(String value) { surname = value; }
}
Instead of the annotations, I'd suggest a mapping class like:
class PersonEntity extends Entity {
@Override
public Class getEntityClass() { return Person.class;}
@Override
public Collection getPersistentProperties() {
LinkedList result = new LinkedList<>();
result.add(new PersistentProperty(Person#getFirstname, Person#setFirstname);
result.add(new PersistentProperty(Person#getSurname, Person#setSurname);
return result;
}
}
The fictional "#" sign in this pseudo java code represents a method literal, which, when invoked on an instance of the given class, invokes the corresponding delegate (signed with "::" since java 8) of that instance. The "PersistentProperty" class should be able to enforce the method literals to be referring to the given generic argument, in this case the class Person.
This way, you have more benefits than annotations can deliver (like subclassing your 'annotate'-class) and you have none of the aforementioned cons. You can have more domain-specific approaches too. The only pre annotations have over this, is that with annotations you can quickly see whether you have forgotten to include a property/method. But this too can be handled more concise and more correct with better metadata support in Java (think for instance of something like required/optional like in Protocolbuffers)