今天看下了spring的源码,看到AbstractAutowireCapableBeanFactory类中creanbean方法自动创建bean时,用到了反射,下面就我看到的spring中package org.springframework.util 下的ReflectionUtils 和beanutils中下总结了,也和大家共同学习:
beanutils 中的copyProperties(Object source, Object target)大家一定不会陌生,apache中也用这个方法,大家也经常用,原理都是用到了反射:
private static void copyProperties(Object source, Object target, Class editable, String[] ignoreProperties) throws BeansException { Assert.notNull(source, "Source must not be null"); Assert.notNull(target, "Target must not be null"); // 我们用到的editable,ignoreProperties 一般都为空,但是我个人觉得ignoreProperties 还是挺有用的,过滤些不要的属性 Class actualEditable = target.getClass(); if (editable != null) { if (!editable.isInstance(target)) { throw new IllegalArgumentException("Target class [" + target.getClass().getName() + "] not assignable to Editable class [" + editable.getName() + "]"); } actualEditable = editable; } PropertyDescriptor[] targetPds = getPropertyDescriptors(actualEditable); List ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null; for (int i = 0; i < targetPds.length; i++) { PropertyDescriptor targetPd = targetPds[i]; if (targetPd.getWriteMethod() != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) { PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName()); if (sourcePd != null && sourcePd.getReadMethod() != null) { try { Method readMethod = sourcePd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source, new Object[0]); Method writeMethod = targetPd.getWriteMethod(); if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) { writeMethod.setAccessible(true); } writeMethod.invoke(target, new Object[] {value}); } catch (Throwable ex) { throw new FatalBeanException("Could not copy properties from source to target", ex); } } } } }
再说下PropertyDescriptor类
PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
1、getPropertyType(),获得属性的Class对象。
2、getReadMethod(),获得用于读取属性值的方法;
getWriteMethod(),获得用于写入属性值的方法。
3、hashCode(),获取对象的哈希值。
4、setReadMethod(Method readMethod),设置用于读取属性值的方法;setWriteMethod(MethodwriteMethod),设置用于写入属性值的方法
调用其方法应优先使用java.beans.PropertyDescriptor获取Method进行方法调用,以获得更大的可维护性。
在ReflectionUtils中有很多小方法 看来简单其实是很实用的
比如在一个class查找某个属性
public static Field findField(Class clazz, String name, Class type) { Assert.notNull(clazz, "Class must not be null"); Assert.isTrue(name != null || type != null, "Either name or type of the field must be specified"); Class searchType = clazz; while (!Object.class.equals(searchType) && searchType != null) { Field[] fields = searchType.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) { return field; } } //查找父类的属性 searchType = searchType.getSuperclass(); } return null; }在class中查找某个方法
public static Method findMethod(Class clazz, String name, Class[] paramTypes) { Assert.notNull(clazz, "Class must not be null"); Assert.notNull(name, "Method name must not be null"); Class searchType = clazz; while (!Object.class.equals(searchType) && searchType != null) { Method[] methods = (searchType.isInterface() ? searchType.getMethods() : searchType.getDeclaredMethods()); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; if (name.equals(method.getName()) && (paramTypes == null || Arrays.equals(paramTypes, method.getParameterTypes()))) { return method; } } searchType = searchType.getSuperclass(); } return null; }
某属性是否是final、static、public来修饰
public static boolean isPublicStaticFinal(Field field) { int modifiers = field.getModifiers(); return (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)); }
标记某个数据有访问权限
public static void makeAccessible(Field field) { if (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())) { field.setAccessible(true); } }有一种代码的写法也在我们代码中很实用,但是我们很少这样去写,我个人认为这样写比较清晰
public static Method[] getAllDeclaredMethods(Class leafClass) throws IllegalArgumentException { final List list = new ArrayList(32); doWithMethods(leafClass, new MethodCallback() { public void doWith(Method method) { list.add(method); } }); return (Method[]) list.toArray(new Method[list.size()]); } public static interface MethodCallback { /** * Perform an operation using the given method. * @param method the method to operate on */ void doWith(Method method) throws IllegalArgumentException, IllegalAccessException; }
相关推荐
Java仿Spring框架IOC控制反转利用反射简单实现(源码) Java仿Spring框架IOC控制反转利用反射简单实现(源码)
《Java语言的反射机制.pdf》资料书,示例源代码JAVA+Spring,初学java反射者可以看看
最近在看spring源码 搜集了这一本大家都推荐的《spring揭秘》PDF 非常不错,同时附带spring源码下载地址 以及编译方式,照着做就可以,本人已经测试; ps spring 涉及动态代理、反射、设计模式之类的先弄懂再看,...
主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射
NULL 博文链接:https://zmx.iteye.com/blog/688299
NULL 博文链接:https://zyqwst.iteye.com/blog/2255560
4、实例化 将扫描到的相关类,利用反射机制实例化,并且保存到IOC容器之中 5、依赖注入 (DI)自动给IOC容器中的对象,需要自动赋值的属性赋值 6、HandlerMapping 将一个url对应一个Method,将这样的关系保存起来, ...
NULL 博文链接:https://dolphin-ygj.iteye.com/blog/548314
我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring框架——从一个...
1、 需要去构造一个Spring容器:ClassPathXmlApplicationContext; 2、 需要注解定义两个注解:@Service、@Resource; 3、 使用反射的手段读取指定目录下的class信息,解析Class信息; 4、 对Class信息的注解做处理...
该demo集成了spring+springmvc+hibernate框架,里面的dao、service、entity均采用注解形式,容易开发,另外该demo中dao采用注解形式,将所有实体dao需要用到的通用方法如insert,update,delete,分页查询等均采用...
工程介绍:SpringBoot项目脚手架,利用spring aop+java反射实现自定义注解校验参数 源码里有使用都例子在DemoContorller example1:校验userName参数必填 @CheckParams(notNull = true) private String userName;...
Java基础 反射篇 - Java基础 反射篇 - 反射的思想及作用 - 反射的基本使用 - 获取类的 Class 对象 - 构造类的实例化对象 - 获取一个类的所有信息 ...反射是开源框架中的一个重要设计理念,在源码
ConfigHandler类将根据该结点下的内容处理并创建一ConfigInfo对象(关于ConfigInfo、 ObjectInfo以及PropertyInfo的代码可自行查看源代码,这里就不再赘述)。ConfigHandler类的代码实现如下: using System; using ...
NULL 博文链接:https://arne3166.iteye.com/blog/1046340
我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个...
AOP:面向切面,不修改源代码进行功能增强 Spring特点 方便解耦,简化开发 AOP支持 方便测试 如Junit5 集成其他框架 方便进行事务操作 降低APi开发难度 2.IOC容器 IOC底层原理 XML解析、工厂模式、反射 通过加载配置...
NULL 博文链接:https://bijian1013.iteye.com/blog/2299135
COS 426计算机图形学比赛参赛作品作为COS 426计算机图形学的一部分,这是2020年Spring开设的普林斯顿计算机科学高级课程,邀请学生在课程分配的基础上进行思考,设计和实施其他功能,以提交给全职员工评判的全班竞赛...