现有一个特殊JavaBean,里面有4个字段,分别是
id,type,title,content。
假设还有一个UserInfoVO,里面有
id,userName,nickName,telphone,mail,address
等字段信息,
想要将UserInfoVO里面的id set到JavaBean里面的id,将userName,或者nickName set到title,将telphone,mail,address等信息set到content,现在只有这一个UserInfoVO所以你可以这样写:
setId(UserInfoVO.getId());
setTitle(UserInfoVO.getTitle());
setContent(UserInfoVO.getContent());
但是如果有多个这样的VO呢,是不是要为每个类写一遍呢?显然不是的,我们只是不知道每个VO中哪个字段要set到id中,哪个字段要set到title中,现在我们定义如下注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(value={ElementType.TYPE})
@Inherited
public @interface VoAnnotion {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD })
@Inherited
public @interface VoField {
String name();
String value();
}
@VoAnnotion
public class UserInfoVO {
private String id;
private String name;
private String tel;
private String email;
private String address;
@VoField(name = "id" , value ="id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@VoField(name = "title" , value ="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@VoField(name = "content" , value ="tel")
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@VoField(name = "content" , value ="email")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
我们想把什么字段set进id就在那个字段的get方法上写上注解@VoField(name = “id”, value=”id”)。这里要解释一下注解的作用:注解其实是给某个类或某个方法或某个字段加上标签,比如说:给一个方法插上一个的标签,那么在程序中用到这个方法时就能知道这是我当初定义过的,要怎么使用就看自己的业务了。name = “id”,当我以后用到这个方法时,我就知道这个方法的值是要被set进id中的。
注解中:
ElementType.TYPE:能修饰类、接口或枚举类型
ElementType.FIELD:能修饰成员变量
ElementType.METHOD:能修饰方法
ElementType.PARAMETER:能修饰参数
ElementType.CONSTRUCTOR:能修饰构造器
ElementType.LOCAL_VARIABLE:能修饰局部变量
ElementType.ANNOTATION_TYPE:能修饰注解
ElementType.PACKAGE:能修饰包
/**
* 解析带注解的vo,组装luceneExtendVO
* @author JiaJiCheng
*
*/
public class AssemblyLuceneVOUtil {
private static final Log LOG = LogFactory.getLog(AssemblyLuceneVOUtil.class);
/**
* 将VO转换成BeanLuceneExtend对象
* @param obj
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public static BeanLuceneExtend objToLuceneExtend(Object obj)
{
try
{
if(obj == null)
{
return null;
}
StringBuilder id = new StringBuilder();
StringBuilder type = new StringBuilder();
StringBuilder title = new StringBuilder();
StringBuilder content = new StringBuilder();
// 得到类的抽象数据类型
Class clazz = obj.getClass();
// 判断是否是自己定义的注解类
if(clazz.isAnnotationPresent(VoAnnotion.class))
{
BeanInfo info = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] props = info.getPropertyDescriptors();
for(PropertyDescriptor prop : props)
{
// 获取类中的get方法
Method method = prop.getReadMethod();
String name = prop.getName();
if (method == null || "class".equals(name)) {
continue;
}
if (!method.isAccessible()) {
method.setAccessible(true);
}
// invoke方法为 执行get方法,obj是依赖的类,((Object[]) null)是方法的参数。
Object value = method.invoke(obj, (Object[]) null);
if (value != null && method.isAnnotationPresent(VoField.class)) {
// 拿到当前get方法的注解
VoField annotionName = method.getAnnotation(VoField.class);
makeParamByAnnotion(annotionName, value, id, type, title, content);
}
}
return makeParam(id, type, title, content);
}
}catch(Exception e)
{
LOG.error("构造BeanLunceneExtend对象失败 " + e.toString());
}
return null;
}
private static BeanLuceneExtend makeParam(StringBuilder id, StringBuilder type, StringBuilder title, StringBuilder content)
{
BeanLuceneExtend extend = new BeanLuceneExtend();
extend.setId(id.toString());
extend.setType(type.toString());
extend.setContent(content.deleteCharAt(content.length()-1).toString());
extend.setTitle(title.toString());
return extend;
}
/**
* 根据注解读取内容,组装内容
* @param voField 注解vo
* @param value get方法的值
* @return
*/
private static void makeParamByAnnotion(VoField voField, Object value, StringBuilder id, StringBuilder type, StringBuilder title, StringBuilder content)
{
if(value == null || "".equals(value) || voField == null)
{
return;
}
//字段是id
if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.ID.toString()))
{
LOG.info("****start to assemble id****");
if(id == null || id.length() == 0)
{
id.append(voField.value() + ":");
}
id.append(value);
}
else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.TYPE.toString()))
{
LOG.info("****start to assemble type****");
if(type == null || type.length() == 0)
{
type.append(voField.value() + ":");
}
type.append(value);
}
else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.TITLE.toString()))
{
LOG.info("****start to assemble title****");
if(title == null || title.length() == 0)
{
title.append(voField.value() + ":");
}
title.append(value);
if(content == null || content.length() == 0)
{
content.append(voField.value() + ":");
}
content.append(value).append(",");
}
else if(voField.name().toUpperCase().equals(LuceneExtendFieldEnum.CONTENT.toString()))
{
LOG.info("****start to assemble content****");
if(content == null || content.length() == 0)
{
content.append(voField.value() + ":");
}
content.append(value).append(",");
}
}
}