`
wuxing429
  • 浏览: 16138 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

看spring源码学反射

 
阅读更多

今天看下了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源代码解析

    同时,了解Spring源码也有助于开发者更好地选择和集成其他Java库,提升开发效率和应用性能。 总结来说,Spring源代码解析涵盖了IoC容器的运作、AOP的实现、数据访问的策略以及Web MVC的流程。深入研究这些内容,将...

    spring揭秘 附带spring源码获取方式

    最近在看spring源码 搜集了这一本大家都推荐的《spring揭秘》PDF 非常不错,同时附带spring源码下载地址 以及编译方式,照着做就可以,本人已经测试; ps spring 涉及动态代理、反射、设计模式之类的先弄懂再看,...

    spring源代码下载(共3部分)

    源代码是理解任何软件系统精髓的最佳途径,Spring的源代码也不例外。本篇将详细讲解Spring源代码下载的重要性和如何深入学习Spring的源代码。 首先,了解Spring源代码能够帮助开发者深入理解框架的工作原理,这对于...

    spring源码文件压缩

    这个压缩包"spring源码文件压缩"很可能包含了Spring框架的核心组件和模块的源代码。 在Spring源码中,主要涉及以下几个关键知识点: 1. **依赖注入(Dependency Injection, DI)**:这是Spring的核心特性,它通过...

    主题:学习Spring必学的Java基础知识(1)----反射

    主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射主题:学习Spring必学的Java基础知识(1)----反射

    Java仿Spring框架IOC控制反转利用反射简单实现(源码)

    本篇文章将详细探讨如何通过反射机制来实现一个简单的Java IOC容器,以此来模仿Spring框架的行为。 首先,理解控制反转(IOC)的概念至关重要。在传统的编程模式中,对象通常自行创建依赖对象,而在IOC中,这种创建...

    spring源码缺失的jar包

    当我们在导入Spring源码时,如果没有这些jar包,编译器无法识别和处理源码中的类和方法,从而导致错误。 首先,我们来详细了解Spring的核心组件: 1. **AOP库**:Spring的AOP模块提供了一种声明式的方式来进行横切...

    spring源码, 可以很好的学习spring源码, 对spring更深入理解

    总之,通过深入学习Spring源码,开发者不仅可以提升编程能力,还能掌握更多软件设计和架构方面的知识,对于职业发展大有裨益。在实际开发中,结合源码理解,能够更好地解决遇到的问题,优化代码,提高工作效率。

    spring源码

    要深入理解Spring源码,你需要熟悉Java、反射、动态代理、设计模式等基础知识。此外,了解Gradle构建工具的使用也是很重要的,因为源码已经用Gradle构建过,可以方便地在Eclipse中导入和构建项目。通过阅读和分析...

    Spring源码编译缺少的两个包:spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.2.jar

    在本案例中,"Spring源码编译缺少的两个包:spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.2.jar"揭示了这两个关键的库对于Spring源码编译是必不可少的。下面将详细讲解这两个库的作用及其在Spring中的...

    Spring核心源码解析.pdf

    本篇文档将对Spring框架的核心源码进行解析,以帮助开发者更深入地理解Spring的工作原理和核心概念。 首先,Spring框架通过使用IoC容器来管理应用对象的创建和依赖关系。这种做法可以让程序员从创建对象的复杂性中...

    spring源码合集spring源码合集

    《Spring源码合集:揭示Java后端开发的基石》 Spring框架作为Java后端开发的核心,其源码的研究对于提升开发者对系统架构理解和优化能力至关重要。本合集深入剖析了Spring的诸多关键特性,包括依赖注入、配置类解析...

    Spring源码

    通过深入学习Spring源码,我们可以了解到设计模式的运用,例如工厂模式、代理模式、装饰者模式等,以及如何利用反射、动态代理等Java核心技术实现IoC和AOP。此外,源码中还包括了对Spring Boot、Spring MVC等模块的...

    spring 源码

    总的来说,Spring源码的研究可以帮助我们深入理解依赖注入、面向切面编程、以及各种企业级应用开发的最佳实践。通过对Spring源码的学习,开发者可以更加熟练地运用Spring框架,设计出更加高效、可维护的系统。同时,...

    spring 4.3 源代码

    《Spring框架4.3源码深度解析》 Spring框架作为Java开发中的核心组件,自诞生以来就备受开发者青睐。4.3版本是Spring发展过程中的一个重要里程碑,它引入了诸多新特性和改进,提升了框架的稳定性和性能。本文将深入...

    spring源码(编译好了,可以直接导入eclipse)

    标题提到的"spring源码(编译好了,可以直接导入eclipse)"表明这个压缩包包含的是已经编译完成的Spring框架源代码,可以直接在Eclipse集成开发环境中使用,便于学习和调试。 首先,Spring框架的核心组成部分包括...

    spring IOC学习源码

    `.idea`文件夹是IntelliJ IDEA的工作空间配置,与Spring源码学习关联不大,通常在提交代码时会被忽略。 为了深入理解Spring IOC,我们需要关注以下几个源码的关键部分: 1. **BeanDefinitionReader**:读取XML配置...

    Spring源码+配套gradle研究Spring源码可直接使用

    要研究Spring源码,你需要对Java语言、设计模式、反射和动态代理有深入理解。Gradle的使用则需要了解其基本语法和插件系统。在阅读源码的过程中,可以从核心接口和实现类入手,例如ApplicationContext接口及其实现,...

    Spring2(源码)

    Spring框架是Java开发中最常用的轻量级开源框架之一,它...以上是对Spring框架的一些核心概念和关键点的介绍,深入研究Spring源码可以帮助我们更好地理解其实现细节,提高开发效率,并为定制化开发和性能优化提供基础。

Global site tag (gtag.js) - Google Analytics