利用注解和反射将map转化成bean

一、java注解

java注解相关的类放在 java.lang.annotation 包下,其主要内容包含4个元注解和其中两个元注解的枚举类值,相对比较简单,从jdk问答即可了解

4个元注解:

Documented:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用
Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。

Inherited:指示注释类型被自动继承。如果在注释类型声明中存在 Inherited
元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。此过程会重复进行,直到找到此类型的注释或到达了该类层次结构的顶层
(Object) 为止。如果没有超类具有该类型的注释,则查询将指示当前类没有这样的注释。

注意,如果使用注释类型注释类以外的任何事物,此元注释类型都是无效的。还要注意,此元注释仅促成从超类继承注释;对已实现接口的注释无效。

Retention:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为
RetentionPolicy.CLASS

只有元注释类型直接用于注释时,Target 元注释才有效。如果元注释类型用作另一种注释类型的成员,则无效。

RetentionPolicy.SOURCE ---------------------------------注解将被编译器丢弃

RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但会被VM丢弃

RetentionPolicy.RUNTIME VM-------将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

Target: 指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target
元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制

ElemenetType.CONSTRUCTOR----------------------------构造器声明

ElemenetType.FIELD --------------------------------------域声明(包括 enum 实例)

ElemenetType.LOCAL_VARIABLE------------------------- 局部变量声明

ElemenetType.METHOD ----------------------------------方法声明

ElemenetType.PACKAGE --------------------------------- 包声明

ElemenetType.PARAMETER ------------------------------参数声明

ElemenetType.TYPE--------------------------------------- 类,接口(包括注解类型)或enum声明

二、注解例子

该例子有3个文件:注解类Annotation_1、使用注解类UseAnnotation、解析注解类ParseAnnotation

package com.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation_1 {

	String name();

	int id() default 0;

	Class gid();

}
package com.annotation;

import java.lang.reflect.Method;

@Annotation_1(name="useAnnotation", id=1, gid=Long.class)
public class UseAnnotation {

	@Annotation_1(name="a", gid=Integer.class)
	public int a;

	@Annotation_1(name="constractor_method", gid=Method.class)
	public UseAnnotation(){

	}

	@Annotation_1(name="getA", id=2, gid=Method.class)
	public int getA(){
		return this.a;
	}

	@Annotation_1(name="setA", id=2, gid=Method.class)
	public void setA(int a){
		this.a = a;
	}
}
package com.annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ParseAnnotation {

	/**
	 * 解析类的注解
	 * @throws ClassNotFoundException 
	 */
	public void parseClass() throws ClassNotFoundException{
//		Class clazz = Class.forName("com.annotation.UseAnnotation");
		Annotation[] as = UseAnnotation.class.getAnnotations();
		for(Annotation a: as){
			Annotation_1 a1 = (Annotation_1)a;
			System.out.println("CLASS: name=" + a1.name() + ", id=" + a1.id() + ", gid=" + a1.gid());
		}
	}

	/**
	 * 解析方法的注解
	 */
	public void parseMethod(){
		Method[] methods = UseAnnotation.class.getMethods();
		this.parse(methods);
	}

	/**
	 * 解析成员变量的注解 
	 */
	public void parseField(){
		Field[] fields = UseAnnotation.class.getFields();
		this.parse(fields);
	}

	private <T extends AccessibleObject> void parse(T[] ts){
		for(T t: ts){
			Annotation annotation = t.getAnnotation(Annotation_1.class);
			if(annotation == null){
				System.out.println(t.getClass().getName() + " do not have Annotation_1");
			}else{
				Annotation_1 a1 = (Annotation_1)annotation;
				System.out.println(t.getClass().getName() + ": name=" + a1.name() + 
						", id=" + a1.id() + ", gid=" + a1.gid());
			}
		}
	}

	public static void main(String[] args) throws ClassNotFoundException {
		ParseAnnotation pa = new ParseAnnotation();
		pa.parseClass();
		pa.parseMethod();
		pa.parseField();
	}

}

三、利用注解和反射将map转化成bean

该例子使用注解和反射的技术将map类型转化成对应的bean

主要包含4个类:注解类PojoAnnotation、bean类User、转换工具类PojoMappingUtil、测试类PojoTest

package com.annotation.userdemo;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface PojoAnnotation {
	String name();
}
package com.annotation.userdemo;

public class User {

	@PojoAnnotation(name="NAME")
	private String name;

	@PojoAnnotation(name="AGE")
	private Integer age;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [name=" + name + ", age=" + age + "]";
	}

}
package com.annotation.userdemo;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class PojoMappingUtil {

	/**
	 * 将map中key与注解一致的值放到对应成员变量中
	 */
	public static <T> T parsePoje(Map<String, Object> map, Class<T> clazz) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
		T t = clazz.newInstance();
		Field[] fields = clazz.getDeclaredFields();
		for(Field field : fields){
			PojoAnnotation pojoAnnotation = field.getAnnotation(PojoAnnotation.class);
			if(pojoAnnotation != null){
				Object o = map.get(pojoAnnotation.name());
				if(o != null){
					String fieldName = field.getName();
					Method method = clazz.getMethod("set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1), o.getClass());
					method.invoke(t, o);
				}
			}
		}
		return t;
	}

}
package com.annotation.userdemo;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

public class PojoTest {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

		Map<String, Object> map = new HashMap<String , Object>();
		map.put("NAME", "小明");
		map.put("AGE", 10);
		User user = PojoMappingUtil.parsePoje(map, User.class);
		System.out.println(user);

	}

}
时间: 2024-10-13 02:07:55

利用注解和反射将map转化成bean的相关文章

[杂记]自定义注解以及反射的应用

序:对于注解的认知是从spring开始的,不管是aop还是ioc,对于其概念是比较清楚的,但真正的实现却没有一个比较好的认知,前段时间看了下<从零开始写web框架>,但当时看的比较仓促,再说因为时间的原因,并没有细揪很多东西,这两天研究了下公司一个系统的代码,突然间对于这块有了比较好的理解,故做潦草记录. 项目使用自定义注解和反射主要是为了在webSocket请求发过来的时候,通过请求中的参数定位到类和方法,然后去执行具体的业务逻辑,具体整个流程如下. 1.自定义注解 @Target(Elem

Java高级之注解、反射

Java的注解.反射等机制的产生,让动态代理成为可能,一般通过全限定名+类名,找到类,可以invoke它的构造方法以及其他方法,可以获取它的参数(Field)名称和值. 注解一般用在代码的注释上.代码审查上(有没有按标准写,比如inspect).代码注入(hook,asbectj),需要考虑的是,在何时注入(编译期还运行期) 反射一般用在动态将json和Object互相转化,执行相关底层代码,比如设置某个类的Accessible为false,防止别人hook修改 例:阿里的FastJson解析:

理解Android中的注解与反射

前言 最近一段时间在研究EventBus和Retrofit 的过程中,都遇到了注解这个概念.由于在学习Java的时候对这方面没有深入了解过,所以看起相关的代码来,总会有点不知其所以然,这里就注解和反射的使用做一下总结. 这里我们先从反射说起,了解了反射的意义及用法后,我们在看看注解的使用,最后叙述一下在Android开发中是怎样结合使用注解与反射. 反射 Java反射(Reflection)定义 Java反射机制是指在运行状态中 对于任意一个类,都能知道这个类的所有属性和方法: 对于任何一个对象

【Android数据库优化】利用注解实现SQLite通用框架抽取

在开发Android应用的过程中,少不了要用到SQLite数据库操作,各种增删查改...一般看来,对于不同的实体类的数据库操作,貌似我们只能使用不同的"增删查改"方法来实现,本次的想法就是,能不能抽取出一个通用的框架,使得对于不同的实体类的数据库操作,可以使用同一个接口的实现来做...废话少说,进入正题. 一.普通的数据库操作的实现 现在有一个Book的类,里面有三个成员变量,id,tittle和summary,其中id将会作为主键,且自增.Book代码如下: package com.

Spring框架中利用注解进行自动装配的环境配置步骤和常见问题

第1步:配置XML文件 ,如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.spring

spring利用注解来注册bean到容器

1.spring利用注解来定义bean,或者利用注解来注册装配bean.包括注册到ioc中,装配包括成员变量的自动注入. 1.spring会自动扫描所有类的注解,扫描这些注解后,spring会将这些bean注册到ioc容器中.省去了xml文件的书写bean方法. 2.spring会自动扫描这些注解,spring会自动扫描这些注解. 配置<context:component-sacn base-package="xxxx">后,spring就会自动扫描注解.扫描指定包下所有内

java自定义注解与反射

java注解与反射一.Java中提供了四种元注解,专门负责注解其他的注解,分别如下 1.@Retention元注解,表示需要在什么级别保存该注释信息(生命周期).可选的RetentionPoicy参数包括: RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉 RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认) RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注

java中Map转化为bean

Map 集合类用于存储元素对(称作"键"和"值"),其中每个键映射到一个值,在java编程中会经常用到.但是当我们进行业务逻辑的处理或着操作数据库时,往往应用的是我们自己定义的的Bean或VO来传递和存储数据,这就需要我们应用一个公共方法来将map中存储的数据转换为相对应的Bean或VO,主要用到java中反射技术. 以下为本人在项目中用到的工具类,它囊括了我们常用的数据类型,代码如下: package test; import java.lang.reflect.

注解与反射-复习

目录 注解 内置注解 元注解 自定义注解 反射机制 简介 Class类 Java内存 类加载的过程 ClassLoader 反射获取运行时类的结构信息 动态创建对象 通过反射创建对象 (一般情况) 通过"构造器对象"创建对象 (不存在无参构造) 通过反射调用成员: method field 测试: 性能分析 反射获取泛型数据 反射获取注解数据 基于B站秦疆老师的课. 感谢! 注解 @since JDK1.5 不是程序本身, 可以对程序做出解释, 可以被其他程序读取(如 编译器) 内置注