今天看下了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; }
相关推荐
同时,了解Spring源码也有助于开发者更好地选择和集成其他Java库,提升开发效率和应用性能。 总结来说,Spring源代码解析涵盖了IoC容器的运作、AOP的实现、数据访问的策略以及Web MVC的流程。深入研究这些内容,将...
最近在看spring源码 搜集了这一本大家都推荐的《spring揭秘》PDF 非常不错,同时附带spring源码下载地址 以及编译方式,照着做就可以,本人已经测试; ps spring 涉及动态代理、反射、设计模式之类的先弄懂再看,...
源代码是理解任何软件系统精髓的最佳途径,Spring的源代码也不例外。本篇将详细讲解Spring源代码下载的重要性和如何深入学习Spring的源代码。 首先,了解Spring源代码能够帮助开发者深入理解框架的工作原理,这对于...
这个压缩包"spring源码文件压缩"很可能包含了Spring框架的核心组件和模块的源代码。 在Spring源码中,主要涉及以下几个关键知识点: 1. **依赖注入(Dependency Injection, DI)**:这是Spring的核心特性,它通过...
主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射
本篇文章将详细探讨如何通过反射机制来实现一个简单的Java IOC容器,以此来模仿Spring框架的行为。 首先,理解控制反转(IOC)的概念至关重要。在传统的编程模式中,对象通常自行创建依赖对象,而在IOC中,这种创建...
当我们在导入Spring源码时,如果没有这些jar包,编译器无法识别和处理源码中的类和方法,从而导致错误。 首先,我们来详细了解Spring的核心组件: 1. **AOP库**:Spring的AOP模块提供了一种声明式的方式来进行横切...
总之,通过深入学习Spring源码,开发者不仅可以提升编程能力,还能掌握更多软件设计和架构方面的知识,对于职业发展大有裨益。在实际开发中,结合源码理解,能够更好地解决遇到的问题,优化代码,提高工作效率。
要深入理解Spring源码,你需要熟悉Java、反射、动态代理、设计模式等基础知识。此外,了解Gradle构建工具的使用也是很重要的,因为源码已经用Gradle构建过,可以方便地在Eclipse中导入和构建项目。通过阅读和分析...
在本案例中,"Spring源码编译缺少的两个包:spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.2.jar"揭示了这两个关键的库对于Spring源码编译是必不可少的。下面将详细讲解这两个库的作用及其在Spring中的...
本篇文档将对Spring框架的核心源码进行解析,以帮助开发者更深入地理解Spring的工作原理和核心概念。 首先,Spring框架通过使用IoC容器来管理应用对象的创建和依赖关系。这种做法可以让程序员从创建对象的复杂性中...
《Spring源码合集:揭示Java后端开发的基石》 Spring框架作为Java后端开发的核心,其源码的研究对于提升开发者对系统架构理解和优化能力至关重要。本合集深入剖析了Spring的诸多关键特性,包括依赖注入、配置类解析...
通过深入学习Spring源码,我们可以了解到设计模式的运用,例如工厂模式、代理模式、装饰者模式等,以及如何利用反射、动态代理等Java核心技术实现IoC和AOP。此外,源码中还包括了对Spring Boot、Spring MVC等模块的...
总的来说,Spring源码的研究可以帮助我们深入理解依赖注入、面向切面编程、以及各种企业级应用开发的最佳实践。通过对Spring源码的学习,开发者可以更加熟练地运用Spring框架,设计出更加高效、可维护的系统。同时,...
《Spring框架4.3源码深度解析》 Spring框架作为Java开发中的核心组件,自诞生以来就备受开发者青睐。4.3版本是Spring发展过程中的一个重要里程碑,它引入了诸多新特性和改进,提升了框架的稳定性和性能。本文将深入...
标题提到的"spring源码(编译好了,可以直接导入eclipse)"表明这个压缩包包含的是已经编译完成的Spring框架源代码,可以直接在Eclipse集成开发环境中使用,便于学习和调试。 首先,Spring框架的核心组成部分包括...
`.idea`文件夹是IntelliJ IDEA的工作空间配置,与Spring源码学习关联不大,通常在提交代码时会被忽略。 为了深入理解Spring IOC,我们需要关注以下几个源码的关键部分: 1. **BeanDefinitionReader**:读取XML配置...
要研究Spring源码,你需要对Java语言、设计模式、反射和动态代理有深入理解。Gradle的使用则需要了解其基本语法和插件系统。在阅读源码的过程中,可以从核心接口和实现类入手,例如ApplicationContext接口及其实现,...
Spring框架是Java开发中最常用的轻量级开源框架之一,它...以上是对Spring框架的一些核心概念和关键点的介绍,深入研究Spring源码可以帮助我们更好地理解其实现细节,提高开发效率,并为定制化开发和性能优化提供基础。