-
JAVA工具类:获取类中被指定注解标记的字段值
2020-07-13 15:06:37不说废话直接上代码 /** * @author Sihan Liu */ public class MineBeanUtils { ... * 合并该类和对应父类的所有Fields * @param object object * @return List<Field> */ public static List<Field不说废话直接上代码
/** * @author Sihan Liu */ public class MineBeanUtils { private static final String ERROR_CODE = "-1"; /** * 合并该类和对应父类的所有Fields * @param object object * @return List<Field> */ public static List<Field> mergeAllFields(Object object) { Class<?> clazz = object.getClass(); List<Field> fields = new ArrayList<>(); //排除父级元素,可自定义 while (clazz != null && !Object.class.getName().equals(clazz.getName())) { fields.addAll(Arrays.asList(clazz.getDeclaredFields())); clazz = clazz.getSuperclass(); } return fields; } /** * 获取对象中被注解标记的字段值(可修改为返回List<Object>) * @param t 对象 * @param clazz 注解 * @return 值 */ public static Object getByAnnotation(Object t, Class<? extends Annotation> clazz) { List<Field> fields = mergeAllFields(t); Object value = null; for (Field declaredField : fields) { declaredField.setAccessible(true); if (Modifier.isFinal(declaredField.getModifiers())) { continue; } String object; Object targetObject = getTargetObjectValue(declaredField, t); if (targetObject == null) { object = ERROR_CODE; } else { object = targetObject.toString(); } Object annotation = declaredField.getAnnotation(clazz); if (annotation != null) { //如果多个字段被一个注解标记,在这里修改即可 value = object; } } if (value == null || ERROR_CODE.equals(value)) { throw new RuntimeException("无法获取" + clazz.getSimpleName() + "注解,请检查"); } return value; } /** * 设置对象中被注解标记的字段值 * @param t 对象 * @param value 值 * @param clazz 注解 */ public static void setByAnnotation(Object t, Object value, Class<? extends Annotation> clazz) { List<Field> fields = mergeAllFields(t); for (Field declaredField : fields) { declaredField.setAccessible(true); if (Modifier.isFinal(declaredField.getModifiers())) { continue; } Object annotation = declaredField.getAnnotation(clazz); if (annotation != null) { setTargetObjectValue(declaredField, t, value); break; } } } /** * 通过内省机制获取字段值 * @param declaredField 字段 * @param t 对象 * @return 值 */ public static Object getTargetObjectValue(Field declaredField, Object t) { Object object; try { PropertyDescriptor propDesc = new PropertyDescriptor(declaredField.getName(), t.getClass()); object = propDesc.getReadMethod().invoke(t); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("获取对应数据失败"); } return object; } /** * 通过内省机制设置字段值 * @param declaredField 字段 * @param t 对象 * @param value 值 */ public static void setTargetObjectValue(Field declaredField, Object t, Object value) { try { PropertyDescriptor propDesc = new PropertyDescriptor(declaredField.getName(), t.getClass()); propDesc.getWriteMethod().invoke(t, value); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("写入对应数据失败"); } } }
-
Java注解
2020-12-08 10:52:02注解的具体实现类是Java运行时生成的动态代理类,通过反射获取注解时,返回的是Java运行时生成的动态代理对象。 2.常见注解及其意义 注解包括自定义的注解、JDK内置注解和第三方框架提供的注解 2.1 JDK内置注解 ...1.定义
注解是Annonation接口的一个子接口,注解的作用是为当前读取该注解的程序提供判断依据。注解的具体实现类是Java运行时生成的动态代理类,通过反射获取注解时,返回的是Java运行时生成的动态代理对象。
2.常见注解及其意义
注解包括自定义的注解、JDK内置注解和第三方框架提供的注解
2.1 JDK内置注解
元注解
修饰注解的注解
- @Target:表明作用范围,包括类、接口、字段、方法、参数、构造函数、局部变量、注解等
- @Retention:生命周期,包括SOURCE(被编译器丢弃)、CLASS(在class文件可用,会被JVM丢去)、RUNTIME(JVM使用,作为运行时的判断依据)
- @Documented:被该注解修饰的注解会生成到javadoc中
- @Inherited:可以让注解被“继承”,让子类Class对象使用getAnnotations获取父类中被@Inherited修饰的对象
- @Repeatable:JDK1.8新加入的元注解,表示在同一位置上重复相同的注解
JDK内置注解
- @Override:表明此方法覆盖了父类的方法,生命周期为SOURCE
- @Deprecated:用于标明已经过时的方法和类,生命周期为RUNTIME
- @SuppressWarning:用于有选择的关闭编译器对类、方法和成员变量的警告,生命周期为SOURCE
2.2 第三方框架提供的注解
- Spring IOC相关:@Configuration/@Bean/@Autowired/@Qualifier/@Resource
- Spring MVC相关:@Controller/@Service/@Repository/@Component/@RequestBody/@ResponseBody/@ResController
- Spring AOP相关:@Before/@After/@AfterReturning/@AfterThrowing/@Around
-
Java 注解的读取注解信息的方法
2017-02-07 14:41:37@Retention(RetentionPolicy.RUNTIME) // ...@Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法 @Documented//说明该注解将被包含在javadoc中 public @interfa@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,在运行时可以通过反射获取到 @Target({ElementType.FIELD,ElementType.METHOD})//定义注解的作用目标**作用范围字段、枚举的常量/方法 @Documented//说明该注解将被包含在javadoc中 public @interface FieldMeta { /** * 是否为序列号 * @return */ boolean id() default false; /** * 字段名称 * @return */ String name() default ""; /** * 是否可编辑 * @return */ boolean editable() default true; /** * 是否在列表中显示 * @return */ boolean summary() default true; /** * 字段描述 * @return */ String description() default ""; /** * 排序字段 * @return */ int order() default 0; } 实体类: [java] view plain copy print? public class Anno { @FieldMeta(id=true,name="序列号",order=1) private int id; @FieldMeta(name="姓名",order=3) private String name; @FieldMeta(name="年龄",order=2) private int age; @FieldMeta(description="描述",order=4) public String desc(){ return "java反射获取annotation的测试"; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } 获取到注解的帮助类: [java] view plain copy print? public class SortableField { public SortableField(){} public SortableField(FieldMeta meta, Field field) { super(); this.meta = meta; this.field = field; this.name=field.getName(); this.type=field.getType(); } public SortableField(FieldMeta meta, String name, Class<?> type) { super(); this.meta = meta; this.name = name; this.type = type; } private FieldMeta meta; private Field field; private String name; private Class<?> type; public FieldMeta getMeta() { return meta; } public void setMeta(FieldMeta meta) { this.meta = meta; } public Field getField() { return field; } public void setField(Field field) { this.field = field; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Class<?> getType() { return type; } public void setType(Class<?> type) { this.type = type; } } 运行时获取注解,首先创建一个基类: [java] view plain copy print? public class Parent<T> { private Class<T> entity; public Parent() { init(); } @SuppressWarnings("unchecked") public List<SortableField> init(){ List<SortableField> list = new ArrayList<SortableField>(); /**getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void) * 的直接超类的 Type(Class<T>泛型中的类型),然后将其转换ParameterizedType。。 * getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 * [0]就是这个数组中第一个了。。 * 简而言之就是获得超类的泛型参数的实际类型。。*/ entity = (Class<T>)((ParameterizedType)this.getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; // FieldMeta filed = entity.getAnnotation(FieldMeta.class); if(this.entity!=null){ /**返回类中所有字段,包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段 * entity.getFields();只返回对象所表示的类或接口的所有可访问公共字段 * 在class中getDeclared**()方法返回的都是所有访问权限的字段、方法等; * 可看API * */ Field[] fields = entity.getDeclaredFields(); // for(Field f : fields){ //获取字段中包含fieldMeta的注解 FieldMeta meta = f.getAnnotation(FieldMeta.class); if(meta!=null){ SortableField sf = new SortableField(meta, f); list.add(sf); } } //返回对象所表示的类或接口的所有可访问公共方法 Method[] methods = entity.getMethods(); for(Method m:methods){ FieldMeta meta = m.getAnnotation(FieldMeta.class); if(meta!=null){ SortableField sf = new SortableField(meta,m.getName(),m.getReturnType()); list.add(sf); } } //这种方法是新建FieldSortCom类实现Comparator接口,来重写compare方法实现排序 // Collections.sort(list, new FieldSortCom()); Collections.sort(list, new Comparator<SortableField>() { @Override public int compare(SortableField s1,SortableField s2) { return s1.getMeta().order()-s2.getMeta().order(); // return s1.getName().compareTo(s2.getName());//也可以用compare来比较 } }); } return list; } } 创建子类继承基类: [java] view plain copy print? public class Child extends Parent<Anno>{ } 测试类: [java] view plain copy print? public class TestAnnotation { @SuppressWarnings({ "unchecked", "rawtypes" }) public static void main(String[] args) { Parent c = new Child(); List<SortableField> list = c.init();//获取泛型中类里面的注解 //输出结果 for(SortableField l : list){ System.out.println("字段名称:"+l.getName()+"\t字段类型:"+l.getType()+ "\t注解名称:"+l.getMeta().name()+"\t注解描述:"+l.getMeta().description()); } } }
-
关于JAVA注解的一个例子
2015-03-08 23:03:49在之后的代码中,可以通过反射获取到被打上标记的类、字段、方法,方便做一些逻辑处理,而这些处理内容是你自己编写的,所以注解提供的仅仅是一个标记而已,下面贴上一个注解的应用,场景是通过jdbc获取数据库中的行...大部分头次接触注解的人,应该都是从框架开始的吧,之前感觉注解很神秘,也没有了解过如何基于注解的开发,最近忙里偷闲,学习了一下注解的原理及应用。简单地说,注解就是在类、字段、方法上打一个标记,在之后的代码中,可以通过反射获取到被打上标记的类、字段、方法,方便做一些逻辑处理,而这些处理内容是你自己编写的,所以注解提供的仅仅是一个标记而已,下面贴上一个注解的应用,场景是通过jdbc获取数据库中的行数据Map<String,String>,将该Map转换为相应的POJO
首先是注解的声明,
这里name为该注解的属性,使用时按照格式:@Column(name="xxx")import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { String name(); }
之后是POJO,只有2个属性被打上了注解。public class UserDO { @Column(name = "name") private String userName; @Column(name = "title") private String userTitle; private int loginTimes; private String empId; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserTitle() { return userTitle; } public void setUserTitle(String userTitle) { this.userTitle = userTitle; } public int getLoginTimes() { return loginTimes; } public void setLoginTimes(int loginTimes) { this.loginTimes = loginTimes; } public String getEmpId() { return empId; } public void setEmpId(String empId) { this.empId = empId; } }
通过注解及反射,将Map<String,String>转化为相应的POJO的方法import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; public class ConvertionService { private static List<Field> findFields(Class <?>clazz) { List<Field> fieldList = new ArrayList<Field>(); Set<String>fieldNames = new HashSet<String>(); Class <?>clazzTemp = clazz; while(clazzTemp != Object.class) { Field []fields = clazzTemp.getDeclaredFields(); for(Field field : fields) { if(!fieldNames.contains(field.getName())) {//同名属性子类覆盖 fieldList.add(field); fieldNames.add(field.getName()); } } clazzTemp = clazzTemp.getSuperclass(); } return fieldList; } @SuppressWarnings("unchecked") public static <T> T convertMapToBean(Map<String , String>row , Class<T>clazz) throws InstantiationException, IllegalAccessException { Object object = clazz.newInstance(); List<Field>list = findFields(clazz); for(Field field : list) { if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers())) {//过滤static和final修饰的变量 if(!field.isAccessible()) field.setAccessible(true);//如果是private变量,放开访问的权限 Column columnAnnotation = field.getAnnotation(Column.class); if(columnAnnotation != null) { String value = row.get(columnAnnotation.name());//通过annotation注解的名称来获取对应的值 Class <?>fieldType = field.getType(); if(fieldType == String.class) { field.set(object, value); }else if(fieldType == Integer.class) { field.set(object, getInteger(value)); }else if(fieldType == int.class) { field.setInt(object, getInt(value)); }else if(fieldType == Long.class) { field.set(object, getLongWrapper(value)); }else if(fieldType == long.class) { field.setLong(object , getLong(value)); }/* 继续的数据类型大家可以自己补充 */ }else { /*没有annotation的代码交给大家自己去完成了*/ } } } return (T)object; } public static Integer getInteger(String value) { if (StringUtils.isEmpty(value)) return null; return Integer.valueOf(value); } public static int getInt(String value) { if (StringUtils.isEmpty(value)) return 0; return Integer.valueOf(value); } public static Long getLongWrapper(String value) { if (StringUtils.isEmpty(value)) return null; return Long.valueOf(value); } public static long getLong(String value) { if (StringUtils.isEmpty(value)) return 0; return Long.valueOf(value); } }
测试类的入口方法import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; public class TestMain { public static void main(String []args) throws InstantiationException, IllegalAccessException { @SuppressWarnings({ "unchecked", "serial" }) List<HashMap<String , String>>list = Arrays.asList( new HashMap<String , String>() { { put("name" , "xieyuooo"); put("title" , "小胖"); } }, new HashMap<String , String>() { { put("name" , "ffff"); put("title" , "标题2"); } } ); List<UserDO>users = new ArrayList<UserDO>(list.size()); for(HashMap<String , String> row : list) { users.add(ConvertionService.convertMapToBean(row, UserDO.class)); } System.out.println(); //这里大家可以将users的列表进行输出 } }
-
Java-高级-注解详解
2021-01-13 17:31:57由Java提供的元注解,所谓元注解就是标记其他注解的注解 @Target(约束自定义注解) 用来约束注解可以应用的地方(如方法、类或字段),其中ElementType是枚举类型,也代表可能的取值范围 public enum ElementType { /... -
JAVA 自定义注解 小例
2017-05-11 19:35:50定义Retention(RetentionPolicy....@Target({ElementType.FIELD})//定义注解的作用目标**作用范围字段、枚举的常量/方法 @Documented //说明该注解将被包含在javadoc中 @interface IsShow { }作用域的类型有ElementType -
深入理解Java-注解与反射
2020-10-30 14:41:54注解一般以`@`开始,他像修饰符一样写到类、方法、字段、参数等的前面,以附加一点信息,这种信息可以被编译器使用,也可以通过Java反射功能来获取并使用。 -
注解与枚举
2019-02-18 13:37:01注解与枚举br/>Java除了注释外,还有注解,注解是不同于注释的,注解是可以在运行中获取对对象的信息...对于注解的时机有:source源码级别的,就是这种注解在编译后会被丢弃,class编译级别的,就是这种注解在运... -
day021-反射和注解笔记和代码.rar
2020-03-16 19:57:21用来限制被修饰注解的使用范围,即注解可以在类的哪些成员上使用 @Target 取值使用ElementType.() 1. CONSTRUCTOR:可以在构造器上使用注解 2. FIELD:可以在字段上使用注解 ... -
Java—反射
2020-10-26 14:21:34文章目录Java--反射反射Class获取Class对象判断是否为某个类的实例创建实例获取构造器信息获取类的成员变量(字段)信息调用方法利用反射创建数组反射代码示例获取被注解标注的字段值泛型通配符 WildcardType泛型... -
【拦截工具】Java将判断properties中是否含有某一字段,提取properties文件中一个key对应多个value内容
2019-09-03 20:39:40目录 1、背景 ...原来做的项目上线了,但是将地址作为参数传递到后台请求的时候被我们公司安全部门拦截了,问题是可能将本服务器作为跳板,获取公司内部的数据,可能会出现以下问题: 1.攻击者... -
【Java基础】反射
2020-05-05 17:43:43首先来看一下什么是反射? Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意...通俗点就是反射能操作一个类所拥有的任何东西,类的字段、方法、构造器、注解等。 那么... -
Java EE常用框架.xmind
2020-06-19 16:08:35注解式:通过在执行的Java方法上放置相应的注解完成 Spring与Shiro整合 在web.xml配置拦截器 在Shiro配置文件上配置在web.xml对应的bean 配置安全管理器 配置自定义的realm Shiro过滤器 ... -
Java常用工具包Jodd.zip
2019-07-16 04:51:38获取函数参数名jodd-dboom 数据库访问的轻量级封装,可看作一个简单的ORMjodd-json JSON解析、序列化jodd-vtor 一个基于注解的字段验证框架了解更多: GitHub page (5 min overview): http://oblac.github.io/jodd... -
Java开发实战1200例.第2卷.part3
2013-05-08 22:46:34实例222 设置柱形图文本注解的类别锚点 350 实例223 设置柱形图文本注解旋转锚点 352 实例224 设置柱形图线条注解 354 实例225 绘制柱形效果 355 实例226 柱形图阴影 357 实例227 柱形图阴影偏移 358 实例228 设置... -
Java开发实战1200例.第2卷.part2
2013-05-08 22:45:35实例222 设置柱形图文本注解的类别锚点 350 实例223 设置柱形图文本注解旋转锚点 352 实例224 设置柱形图线条注解 354 实例225 绘制柱形效果 355 实例226 柱形图阴影 357 实例227 柱形图阴影偏移 358 实例228 设置... -
Java开发实战1200例.第2卷.part1
2013-05-08 22:44:13实例222 设置柱形图文本注解的类别锚点 350 实例223 设置柱形图文本注解旋转锚点 352 实例224 设置柱形图线条注解 354 实例225 绘制柱形效果 355 实例226 柱形图阴影 357 实例227 柱形图阴影偏移 358 实例228 设置... -
Java Web开发实战1200例(第2卷)(完整版).(清华出版.卢瀚.王春斌).part1
2016-06-13 20:03:04实例222 设置柱形图文本注解的类别锚点 实例223 设置柱形图文本注解旋转锚点 实例224 设置柱形图线条注解 实例225 绘制柱形效果 实例226 柱形图阴影 实例227 柱形图阴影偏移 实例228 设置柱形的颜色 实例229 绘制3D... -
2.jpa-entity新增swagger@ApiModel@ApiModelProperty注解和SQL字段@Column注解(感谢@yjq907的建议) 2019.11.26 1.springboot2内置tomcat更换为性能更强大的undertow. 2.修复tinyintTransType参数丢失问题 2019....
-
其中: @Autowired注解, 表示从Spring IoC容器中根据类型找到对应的bean,并自动注入到某个字段上 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class...
-
另外在配置 AOP 切面之前,我们需要了解下 aspectj 相关注解的作用: @Aspect:声明该类为一个注解类; @Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为切某个注解,也可以切某个 package 下...
-
一开始自己配置的activiti的运行web时报错以为是环境的问题,后面到网上借鉴改了一些还是没用。
2019-03-21 11:22:27-- 扫描service包下所有使用注解的类型 --> <!-- 配置事务管理器 --> class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入数据库连接池 --> <!-- 配置... -
Spring中文帮助文档
2013-08-05 14:40:1711.5.3. 指定SimpleJdbcInsert所使用的字段 11.5.4. 使用SqlParameterSource提供参数值 11.5.5. 使用SimpleJdbcCall调用存储过程 11.5.6. 声明SimpleJdbcCall使用的参数 11.5.7. 如何定义SqlParameters 11.5.8.... -
4.3.4 在自己的代码中,如果创建一个java.lang.String类,这个类是否可以被类加载器加载?为什么。 4.3.5 说一说你对java.lang.Object对象中hashCode和equals方法的理解。在什么场景下需要重新实现这两个方法。 ...
-
MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 2.1、 MyBatis架构图 跳转到目录 2.2、 MyBatis核心组件 ...
-
接下来就创建一个监听器,使用注解的方式说明: //chk默认为CheckPointH2db,如果不变无需配置。conf:随意,不能重复 rule:监听配置,监听duckula库sys_user表 @BinlogListener(conf = "abc", chk = ...
-
cms后台管理
2012-06-26 10:41:19Jeecms是基于Spring注解,在自定义标签时对于实体类和dao service等注意注解的问题。 五 自定义标签及使用自己创建的表的实现过程 下面是我自己定义的标签mycontent_list 首先,在数据库里创建了一个jc_... -
springmybatis
2015-09-05 06:54:28MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个... -
请求参数 JSON 中表名、字段名、关键词及对应的值都是大小写敏感、逗号敏感、分号敏感、空格敏感、换行敏感, 大部分情况都不允许空格和换行,表名以大写字母开头,不要想当然,请严格按照 设计规范 来调用 API #...
收藏数
32
精华内容
12
-
指令重排序
-
Liunx 优化思路与实操步骤
-
access应用的3个开发实例
-
校园摆渡车的微信小程序.zip
-
DHCP 动态主机配置服务(在Linux环境下,配置单网段或跨网段提)
-
2021年 系统分析师 系列课
-
惠普HP OfficeJet Pro 9018 打印机驱动
-
13种游戏机模拟器源代码.rar
-
SSM-Vue 前后端分离练习
-
大数据ETL入门及实战.pdf
-
基于Qt的LibVLC开发教程
-
《ChinaTeXMathFAQ_V1.1》.pdf
-
H264 SPS中得到宽高的代码(java)
-
HGM2000多线消防广播系统使用说明书.pdf
-
渐进式Web应用程序
-
Kubernetes概述.pdf
-
工程制图 AutoCAD 2012 从二维到三维
-
PowerBI重要外部工具详解
-
JMETER 性能测试基础课程
-
HDX3000消防电话安装使用说明书.pdf