[Java]Annotation元数据的几个应用

来源:百度文库 编辑:神马文学网 时间:2024/04/28 03:19:43
Tiger出笼以后, Annotation成了一个小小的亮点,虽然有抄袭.net之嫌疑,毕竟让Java开发者方便了许多。EJB3.0和Hibernate Annotation版都是基于这个东西了。
下面是结合Spring的自动Log/鉴权/国际化应用:
public interface SessionService extends Service {
    @Anonymous //允许未登录用户调用
    @OperationLog //自动log
    @Name(zh = "登录")
    public String login(
            @Name(en="user",zh = "用户")String user,
            @OperationLog(false)String password); //不log密码

    @OperationLog
    @Name(zh="注销")
    public void logout();
@Anonymous用于鉴权,允许匿名访问。通过ThreadLocal的变量保存当前用户的Session信息。
@OperationLog 用于标记是否自动Log, 可以作用于类、方法、参数
@Name用于i18n国际化支持。Java里面常见的国际化解决方法是.properties文件,个人认为这个方案不好,适合大型项目开发。小项目中这个标记一下足矣。如果要添加一种语言,只要在@Name中多一个参数,利用Eclipse的reference很容易知道有哪些地方要翻译。
同样@Name还可以加在Bean上,自动构造多语言的Table/List,方便之极。
@Name(zh="安全事件",en="Security Event")
public class SecurityEvent extends AbstractEmsEvent{
    String cause;
    @Name(zh="原因")
    public String getCause() {
        return cause;
    }
    
}
附上我的I18nUtil工具类:
/**//**
 * @author steeven
 */
public class I18nUtil {
    public static String getName(Method method) {
        return getI18n(method,Name.class);
    }
    public static String getTip(Method method) {
        return getI18n(method,Tip.class);
    }
    public static String getI18n(Method method,Class i18nClass) {
        Annotation i18n = method.getAnnotation(i18nClass);
        return getProperty(i18n,method.getName());
    }

    public static String getProperty(Annotation i18n, String defaultValue) {
        if (i18n==null)
            return defaultValue;
        Class clz = i18n.annotationType();
        try {
            Method method = clz.getMethod(getI18nMethodName());
            assert method!=null;
            String r = (String) method.invoke(i18n);
            return r==null || r.length()==0?defaultValue:r;
        } catch (Exception e) {
            assert false;
            return defaultValue;
        }
    }

    private static String getI18nMethodName() {
        return Locale.getDefault().getLanguage();
    }

    @SuppressWarnings("unchecked")
    public static  T getAnnotation(Annotation[] argAnnotations, Class clz) {
        for(Annotation anno:argAnnotations)
            if (clz.isInstance(anno))
                return (T) anno;
        return null;
    }
}
元数据的结构似乎有些简单,有时候要加很多@Name,@Tip,@Help好像没办法一个Tag搞定。
另外,还可以通过Annotation加上验证、输入界面描述,等等。程序很容易自动化,再多的画面也用不了多少代码。
Jdk5.0提供了这么好用的原数据机制,你有什么好的用法呢?