发布网友 发布时间:2024-09-30 20:19
共1个回答
热心网友 时间:2024-10-21 01:24
java自定义的注解有什么作用自定义注解,可以应用到反射中,比如自己写个小框架。
如实现实体类某些属性不自动赋值,或者验证某个对象属性完整性等
本人自己用过的验证属性值完整性:
@Target(ElementType.FIELD)???
@Retention(RetentionPolicy.RUNTIME)
public?@interface?IgnoreProperty?{
}
然后实体类中:
public?class?TarResearch?implements?Serializable{
?@IgnoreProperty
?private?static?final?long?serialVersionUID?=?1L;
?@IgnoreProperty
private??Integer?researchId;
?@IgnoreProperty
?private?TarUser?userId;
?private?String?version;
?private?String?grade;
....
???}?
然后action类中??
//?验证数据完整性
??ClassTarResearch??userClass?=?TarResearch?.class;
??Field[]?field?=?userClass.getDeclaredFields();
??for?(int?i?=?0;?i??field.length;?i++)?{
???if?(field[i].getAnnotation(IgnoreProperty.class)?!=?null)?{
????continue;
???}
???String?fie?=?field[i].getName().substring(0,?1).toUpperCase()
?????+?field[i].getName().substring(1);
???Method?method?=?userClass.getMethod("get"?+?fie);
???Object?obj?=?method.invoke(u);
???if?(obj?==?null)?{
????sendResponseMsg(response,?"数据错误");
????return?null;
???}
??}
如何创建,使用以及解析自定义注解首先要想使用自定义注解,必须创建自己的注解类
右键项目,new-Annotation
然后在注解里定义自己的方法,该方法是别的类使用注解时需要填的属性
packagecom.sy.demo.annotation;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceTable{publicStringvalue();}
注:如果只有一个方法时,应该用value()来指定方法名,这样就可以直接简写@Table("xxx")而不是@Table(aaa="xxx");
其中注解类上的注解称为元注解
@Target(ElementType.TYPE)
@Target的意思是,该注解类是放在什么位置的,是放在类上、字段上还是方法上,ElementType.TYPE意思是只能放在类上或接口上,ElementType.FIELD意思是只能放在字段上等等。
如果有多个位置选择可以这么写:
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
意思是作用域,一般写RUNTIME就行
@Documented
意思是是否在生成JavaDoc时加入该注解类,这个看情况写不写
还有其他元注解,想要研究的就自己研究吧
定义完自定义注解了,下面就是使用的时候了
packagecom.sy.demo.entity;importcom.sy.demo.annotation.Column;importcom.sy.demo.annotation.Table;@Table("tdb_user")publicclassUser{@Column("id")privateLongid;@Column("email")privateStringemail;@Column("password")privateStringpassword;publicLonggetId(){returnid;}publicvoidsetId(Longid){this.id=id;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.email=email;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.password=password;}}
在这里我定义了一个实体类,用于表示用户信息,其中还是用了一个@Column类,代码如下
packagecom.sy.demo.annotation;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceColumn{publicStringvalue();}
由代码可知,@Column是放在field上的
使用也使用完了,下面该是解析的时候了。
packagecom.sy.demo.util;importjava.lang.reflect.Field;importcom.sy.demo.annotation.Column;importcom.sy.demo.annotation.Table;publicclassSqlUtil{privatestaticfinalStringEMPTY="";@SuppressWarnings("unchecked")publicstaticStringgetSql(Objectobject){StringBuildersb=newStringBuilder();ClassObjectc;booleanisExist;Columncolumn;StringcolumnName;StringgetMethodName;ObjectcolumnValue;String[]strs;try{c=(ClassObject)object.getClass();isExist=c.isAnnotationPresent(Table.class);if(!isExist){returnEMPTY;}Tabletable=c.getAnnotation(Table.class);sb.append("SELECT*FROM"+table.value()+"WHERE1=1");Field[]fields=c.getDeclaredFields();for(Fieldfield:fields){isExist=field.isAnnotationPresent(Column.class);if(!isExist){continue;}column=field.getAnnotation(Column.class);columnName=column.value();getMethodName="get"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);columnValue=c.getMethod(getMethodName,newClass[0]).invoke(object,newObject[0]);if(columnValue==null){continue;}if(columnValueinstanceofString){columnValue=(String)columnValue;if(((String)columnValue).contains(",")){sb.append("AND"+columnName+"IN(");strs=((String)columnValue).split(",");for(Stringstr:strs){sb.append("'"+str+"',");}sb.deleteCharAt(sb.length()-1);sb.append(")");}else{sb.append("AND"+columnName+"='"+columnValue+"'");}}elseif(columnValueinstanceofInteger||columnValueinstanceofLong){sb.append("AND"+columnName+"="+columnValue+"");}}}catch(Exceptione){e.printStackTrace();}returnsb.toString();}}
解析的时候用的是反射机制,可能看着比较麻烦比较乱,而且也新手可能也不太理解,在用的时候会发现其实还是挺方便的。
原理解释根据反射找到User类,在判断是否有注解,接着拼接sql什么的
整个列子项目中完整的代码如下(有许多步骤测试用例,懒得删了,全贴出来吧)
Controller
packagecom.sy.demo.controller;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importcom.sy.demo.entity.User;importcom.sy.demo.service.IUserService;@Controller@RequestMapping("hello")publicclassUserController{@AutowiredprivateIUserServicehService;@RequestMapping(value="demo1")publicStringdemo1(){return"demo1";}@SuppressWarnings("deprecation")@RequestMapping(value="demo2")publicStringdemo2(){returnhService.test();}@RequestMapping(value="demo3")@ResponseBodypublicStringdemo3(){Useruser=newUser();user.setId(1L);user.setEmail("mr_songyang1990@163.com");user.setPassword("1q2w3e4r,123456,aaaaa");returnhService.getUser(user);}@RequestMapping(value="demo4")@ResponseBodypublicStringdemo4(){Useruser=newUser();user.setId(1L);user.setEmail("mr_songyang1990@163.com");user.setPassword("1q2w3e4r,123456,aaaaa");returnhService.getUser2(user);}}
service:
packagecom.sy.demo.service;importcom.sy.demo.entity.User;publicinterfaceIUserService{@DeprecatedpublicStringtest();publicStringgetUser(Useruser);publicStringgetUser2(Useruser);}
packagecom.sy.demo.service.impl;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importcom.sy.demo.entity.User;importcom.sy.demo.repository.IUserRepository;importcom.sy.demo.service.IUserService;@Service("hService")publicclassUserServiceImplimplementsIUserService{@AutowiredprivateIUserRepositoryhRepository;@Deprecated@OverridepublicStringtest(){return"demo2";}@OverridepublicStringgetUser(Useruser){returnhRepository.queryUser(user);}@OverridepublicStringgetUser2(Useruser){returnhRepository.queryUser2(user);}}
Repository
packagecom.sy.demo.service.impl;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importcom.sy.demo.entity.User;importcom.sy.demo.repository.IUserRepository;importcom.sy.demo.service.IUserService;@Service("hService")publicclassUserServiceImplimplementsIUserService{@AutowiredprivateIUserRepositoryhRepository;@Deprecated@OverridepublicStringtest(){return"demo2";}@OverridepublicStringgetUser(Useruser){returnhRepository.queryUser(user);}@OverridepublicStringgetUser2(Useruser){returnhRepository.queryUser2(user);}}
packagecom.sy.demo.repository.impl;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importorg.springframework.stereotype.Repository;importcom.sy.demo.entity.User;importcom.sy.demo.repository.IUserRepository;importcom.sy.demo.util.DBUtil;importcom.sy.demo.util.SqlUtil;@Repository("hRepository")publicclassUserRepositoryImplimplementsIUserRepository{publicStringqueryUser(Useruser){Stringsql=SqlUtil.getSql(user);System.out.println(sql);returnsql;}@OverridepublicStringqueryUser2(Useruser){StringBuildersb=newStringBuilder();Stringsql=SqlUtil.getSql(user);System.out.println(sql);PreparedStatementps=DBUtil.getPreparedStatement(sql);Longid;Stringemail;Stringpassword;try{ResultSetrs=ps.executeQuery();while(rs.next()){id=rs.getLong("id");email=rs.getString("email");password=rs.getString("password");sb.append("ID:").append(id).append(",email:").append(email).append(",password:").append(password).append("br/");}}catch(SQLExceptione){e.printStackTrace();}returnsb.toString();}}
entity:
packagecom.sy.demo.entity;importcom.sy.demo.annotation.Column;importcom.sy.demo.annotation.Table;@Table("tdb_user")publicclassUser{@Column("id")privateLongid;@Column("email")privateStringemail;@Column("password")privateStringpassword;publicLonggetId(){returnid;}publicvoidsetId(Longid){this.id=id;}publicStringgetEmail(){returnemail;}publicvoidsetEmail(Stringemail){this.email=email;}publicStringgetPassword(){returnpassword;}publicvoidsetPassword(Stringpassword){this.password=password;}}
annotation
packagecom.sy.demo.annotation;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceTable{publicStringvalue();}
packagecom.sy.demo.annotation;importjava.lang.annotation.Documented;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceColumn{publicStringvalue();}
util工具类
packagecom.sy.demo.util;importjava.sql.Connection;importjava.sql.PreparedStatement;importjava.sql.SQLException;importcom.mysql.jdbc.jdbc2.optional.MysqlDataSource;publicclassDBUtil{publicstaticfinalStringURL="jdbc:mysql://localhost:3306/db_test";publicstaticfinalStringUSERNAME="root";publicstaticfinalStringPASSWORD="root";publicstaticConnectionconn=null;publicstaticMysqlDataSourcedataSource;static{dataSource=newMysqlDataSource();dataSource.setUser(USERNAME);dataSource.setPassword(PASSWORD);dataSource.setURL(URL);}publicstaticPreparedStatementgetPreparedStatement(Stringsql){try{conn=dataSource.getConne