现在的位置: 首页 > 综合 > 正文

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

2011年08月29日 ⁄ 综合 ⁄ 共 2389字 ⁄ 字号 评论关闭

 

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<? extends Annotation> 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
<? extends Annotation> 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 extends Annotation> T getAnnotation(Annotation[] argAnnotations, Class<T> clz) {
        
for(Annotation anno:argAnnotations)
            
if (clz.isInstance(anno))
                
return (T) anno;
        
return null;
    }

}

元数据的结构似乎有些简单,有时候要加很多@Name,@Tip,@Help好像没办法一个Tag搞定。

另外,还可以通过Annotation加上验证、输入界面描述,等等。程序很容易自动化,再多的画面也用不了多少代码。

Jdk5.0提供了这么好用的原数据机制,你有什么好的用法呢?

【上篇】
【下篇】

抱歉!评论已关闭.