(spring-第11回【IoC基础篇】)BeanWrapper--实例化Bean的第四大利器
2015-11-29 02:39
435 查看
重复是理解和记忆的最好方法。在讲实例化Bean的每个步骤之前,我都会先复习一下Bean实例化的整个过程:
结合图片我们回顾一下具体的过程:
ResourceLoader加载配置信息,
由BeanDefinitionReader读取并解析<bean>标签,并将<bean>标签的属性都转换为BeanDefinition对应的属性,并注册到BeanDefinitionRegistry注册表中。
容器扫描注册表,通过反射机制获取BeanFactoryPostProcessor类型的工厂后处理器,并用这个工厂后处理器对BeanDefinition进行加工。
取出加工过的BeanDefinition,使用InstantiationStrategy实例化Bean。
BeanWrapper结合BeanDefinitionRegistry和PropertyEditorRegistry对Bean的属性赋值。
今天我们将介绍的就是第五步。开门见山,BeanWrapper的功能:
spring通过BeanWrapper完成属性的配置工作。具体表现为:
从BeanDefinitionRegistry注册表中取出尚未进行属性配置的BeanDefinition,获取Bean属性的配置信息,
使用属性编辑器对这些配置信息进行转换得到Bean属性的值,
最后对Bean通过反射机制设置属性值。
下面是BeanWrapper的继承结构:
从上面的结构可以看出,BeanWrapperImpl(BeanWrapper的实现类)有两个顶级接口,分别是:PropertyEditorRegistry和PropertyAccessor,前者是属性编辑器,负责将配置文件中bean属性的字面值转换为bean具体的属性值。后者定义了各种访问bean属性的方法。所以BeanWrapperImpl具有三重身份:
1. Bean包裹器:(顾名思义)
下面代码是BeanWrapperImpl初始化时要执行的方法,而参数中的object就是包裹的bean对象。
其中第8行就是把object.getClass()保存在cachedIntrospectionResults 属性中,该属性是CachedIntrospectionResults类的实例,
而CachedIntrospectionResults是负责缓存属性描述器(PropertyDescriptor)信息的。
object是对象的实例,而object.getClass()则获取的是实例对应的类的描述信息,那么cachedIntrospectionResults 拿到这个实例类的描述信息class,就可以通过反射机制来访问该class里面的所有属性了,最后封装成PropertyDescriptor。
属性描述器(PropertyDescriptor)是java.beans.PropertyDescriptor包里的类,用来描述java bean的属性(一个描述器描述一个属性),这个属性是JavaBean通过一对入口方法导出的。
BeanWrapperImpl利用属性描述器信息结合属性编辑器来设置属性。
2. 属性访问器:即PropertyAccessor,这个接口有很多方法,诸如:setPropertyValue、setPropertyValues等,BeanWrapperImpl通过这些方法来设置bean属性的值。
3. 属性编辑器注册表:(负责取出属性编辑器,BeanWrapperImpl结合属性编辑器来设置属性)。
下面是BeanWrapperImpl的某个构造函数,一开始就调用了从属性编辑器那里继承过来的registerDefaultEditors方法,该方法自动注册加载spring默认的属性编辑器们。
BeanWrapperImpl完成Bean属性的配置工作之后,接下来还需要Bean后处理器(实现了BeanPostProcessor接口的Bean)继续对Bean实例进行加工,直到装配出一个准备就绪的Bean,把肉放到碗里等萌宝来吃。
由于本文未对代码进行详细解读,所以其中会有没有讲到的地方,比如,属性编辑器具体是怎样的?如何对bean的属性进行编辑?下一篇博文将会详细介绍。
结合图片我们回顾一下具体的过程:
ResourceLoader加载配置信息,
由BeanDefinitionReader读取并解析<bean>标签,并将<bean>标签的属性都转换为BeanDefinition对应的属性,并注册到BeanDefinitionRegistry注册表中。
容器扫描注册表,通过反射机制获取BeanFactoryPostProcessor类型的工厂后处理器,并用这个工厂后处理器对BeanDefinition进行加工。
取出加工过的BeanDefinition,使用InstantiationStrategy实例化Bean。
BeanWrapper结合BeanDefinitionRegistry和PropertyEditorRegistry对Bean的属性赋值。
今天我们将介绍的就是第五步。开门见山,BeanWrapper的功能:
spring通过BeanWrapper完成属性的配置工作。具体表现为:
从BeanDefinitionRegistry注册表中取出尚未进行属性配置的BeanDefinition,获取Bean属性的配置信息,
使用属性编辑器对这些配置信息进行转换得到Bean属性的值,
最后对Bean通过反射机制设置属性值。
下面是BeanWrapper的继承结构:
从上面的结构可以看出,BeanWrapperImpl(BeanWrapper的实现类)有两个顶级接口,分别是:PropertyEditorRegistry和PropertyAccessor,前者是属性编辑器,负责将配置文件中bean属性的字面值转换为bean具体的属性值。后者定义了各种访问bean属性的方法。所以BeanWrapperImpl具有三重身份:
1. Bean包裹器:(顾名思义)
下面代码是BeanWrapperImpl初始化时要执行的方法,而参数中的object就是包裹的bean对象。
其中第8行就是把object.getClass()保存在cachedIntrospectionResults 属性中,该属性是CachedIntrospectionResults类的实例,
而CachedIntrospectionResults是负责缓存属性描述器(PropertyDescriptor)信息的。
object是对象的实例,而object.getClass()则获取的是实例对应的类的描述信息,那么cachedIntrospectionResults 拿到这个实例类的描述信息class,就可以通过反射机制来访问该class里面的所有属性了,最后封装成PropertyDescriptor。
属性描述器(PropertyDescriptor)是java.beans.PropertyDescriptor包里的类,用来描述java bean的属性(一个描述器描述一个属性),这个属性是JavaBean通过一对入口方法导出的。
BeanWrapperImpl利用属性描述器信息结合属性编辑器来设置属性。
public void setWrappedInstance(Object object, String nestedPath, Object rootObject) { Assert.notNull(object, "Bean object must not be null"); this.object = object; this.nestedPath = (nestedPath != null ? nestedPath : ""); this.rootObject = (!"".equals(this.nestedPath) ? rootObject : object); this.nestedBeanWrappers = null; this.typeConverterDelegate = new TypeConverterDelegate(this, object); setIntrospectionClass(object.getClass()); }
protected void setIntrospectionClass(Class clazz) { if (this.cachedIntrospectionResults != null && !clazz.equals(this.cachedIntrospectionResults.getBeanClass())) { this.cachedIntrospectionResults = null; } }
2. 属性访问器:即PropertyAccessor,这个接口有很多方法,诸如:setPropertyValue、setPropertyValues等,BeanWrapperImpl通过这些方法来设置bean属性的值。
3. 属性编辑器注册表:(负责取出属性编辑器,BeanWrapperImpl结合属性编辑器来设置属性)。
下面是BeanWrapperImpl的某个构造函数,一开始就调用了从属性编辑器那里继承过来的registerDefaultEditors方法,该方法自动注册加载spring默认的属性编辑器们。
public BeanWrapperImpl(Object object) { registerDefaultEditors(); setWrappedInstance(object); }
BeanWrapperImpl完成Bean属性的配置工作之后,接下来还需要Bean后处理器(实现了BeanPostProcessor接口的Bean)继续对Bean实例进行加工,直到装配出一个准备就绪的Bean,把肉放到碗里等萌宝来吃。
由于本文未对代码进行详细解读,所以其中会有没有讲到的地方,比如,属性编辑器具体是怎样的?如何对bean的属性进行编辑?下一篇博文将会详细介绍。
相关文章推荐
- Draw 9-patch(点9图)
- material design
- Android之集成友盟推送功能
- Android Studio——R文件小问题
- Android开发之动画(转)
- Android手机出现"已安装了存在签名冲突的同名数据包"的原因及解决办法
- Android:Style详解
- iOS开发>学无止境 - NSLocale的重要性和用法简介
- AJ学IOS 之第三方登录友盟实现
- AJ学IOS之安装cocoapods
- AJ学IOS之去除服务器返回数据中的html标签,去除指定字符串,替换字符串
- iOS开发>学无止境 - Cell 里的视图控制器
- iOS开发>学无止境 - 使用MVC模式帮ViewController瘦身
- AJ学IOS 之ipad开发Popover的调色板应用_popover显示后其他控件仍然能进行交互
- AJ学IOS 之ipad开发Popover的基本使用
- AJ学IOS 之ipad开发qq空间项目横竖屏幕适配
- AJ学IOS 之二维码学习,快速打开相机读取二维码
- AJ学IOS 之二维码学习,快速生成二维码
- AJ学IOS 之tableView的下拉放大图片的方法
- AJ学IOS 之BLOCK的妙用_利用block实现链式编程