java1.5引入了annotation,初看起来非常cool,但是仔细想想它可以被用在什么地方呢?什么样的需求才是用annotation的最佳方式呢?
偶先举几个例子吧:
1. O/R Mapping
比如EJB3的持久化映射, 具体就不用说了, 规范里面非常清楚了, 看代码:
@NamedQueries({ @NamedQuery( name="authorPosts", queryString="select p from Post p where p.author = :author" );, @NamedQuery( name="allPosts", queryString="select p from Post p" ); }); @Entity @Table(name="FORUM_POST", schema="javaeye"); public class Post { private Long _id; private String _title; private String _content; private User _author; @Id(generate=SEQUENCE, generator ="POST_SEQ"); public Long getId(); { return _id; } @Column(name="TITLE", nullable=false, length=255); public String getTitle(); { return _title; } @Column(name="CONTENT", columnDefinition="CLOB NOT NULL"); public String getContent(); { return _content; } @ManyToOne(optional=false); @JoinColumn(name="AUTHOR_ID", nullable=false, updatable=false); public User getAuthor(); { return _author; } }
2. 校验
比如WebWork的visitor方式校验,能够将action的校验,转发到Entity上, 以前的写法是写一个Post-validation.xml:
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"> <validators> <field name="title"> <field-validator type="requiredstring"> <message>Please input title.</message> </field-validator> </field> <field name="content"> <field-validator type="requiredstring"> <message>Please input content.</message> </field-validator> </field> </validators>
改用annotation成:
@Validator(type="requiredstring", message="Please input title."); public String getTitle(); { return _title; } @Validator(type="requiredstring", message="Please input content."); public String getContent(); { return _content; }
3. 索引
比如用lucene做全文搜索,以前是写一个Post-lucene.xml, 当一个Post被持久化的时候,能够自动根据这个配置文件对相应的属性做不同的索引处理:
<lucene> <field type="Keyword" fieldName="title"/> <field type="Text" fieldName="content"/> </lucene>
改用annotation成:
@LuceneIndex(type="KEYWORD"); public String getTitle(); { return _title; } @LuceneIndex(type="TEXT"); public String getContent(); { return _content; }
如果将3种annotation都混合在一起,整个Post Entity将会变成:
@NamedQueries({ @NamedQuery( name="authorPosts", queryString="select p from Post p where p.author = :author" );, @NamedQuery( name="allPosts", queryString="select p from Post p" ); }); @Entity @Table(name="FORUM_POST", schema="javaeye"); public class Post { private Long _id; private String _title; private String _content; private User _author; @Id(generate=SEQUENCE, generator ="POST_SEQ"); public Long getId(); { return _id; } @Column(name="TITLE", nullable=false, length=255); @Validator(type="requiredstring", message="Please input title."); @LuceneIndex(type="KEYWORD"); public String getTitle(); { return _title; } @Column(name="CONTENT", columnDefinition="CLOB NOT NULL"); @Validator(type="requiredstring", message="Please input content."); @LuceneIndex(type="TEXT"); public String getContent(); { return _content; } @ManyToOne(optional=false); @JoinColumn(name="AUTHOR_ID", nullable=false, updatable=false); public User getAuthor(); { return _author; } }
本来干干净净的一个Post POJO,变成了充满annotation的怪家伙,这可以称之为annotation的滥用么?难道又一个AOP出现了?难道以后偶们打开一个Java文件必须用Eclipse之类的IDE,好让它自动将annotation fold,免得花了眼睛么?
你对annotation的意见如何?