这个包的说明是说主要是包括用于操作JavaBean的类和接口,将被大部分spring包使用。在读这个包的代码前,我特意将JavaBean规范读了一遍。JavaBean规范不仅仅是getter、setter,定义了一个完整的轻量级组件模型,事件、方法、属性、持久化等等支持均包含在内。JavaBean规范很明显是学习Delphi的组件模型,sun希望通过它来形成一个java组件的市场,可惜结果不如人意,JavaBean在GUI方面并未形成一个类似delphi控件市场;随着spring等轻量级框架的流行,而EJB重量级的组件模型被越来越多的人放弃,JavaBean反而在服务端模型方面占据了主流
。废话不提,这个包的核心接口和类就是BeanWrapper和BeanWrapperImpl,顾名思义,这个接口就是用于包装JavaBean的行为,诸如设置和获取属性,设置属性编辑器等(PropertyEditor)。看下这个包的核心类图:
BeanWrapper接口继承了PropertyAccessor(用于属性访问和设置)和PropertyEditorRegistry(属性编辑器的获取和设置),而BeanWrapperImpl除了实现BeanWrapper接口外还继承自PropertyEditorRegistrySupport 类。在PropertyEditorRegistrySupport
类中可以看到spring默认设置的一系列自定义PropertyEditor。比如:
<!---->protected void registerDefaultEditors() {
this.defaultEditors = new HashMap(32);
// Simple editors, without parameterization capabilities.
// The JDK does not contain a default editor for any of these target types.
this.defaultEditors.put(Class.class, new ClassEditor());
this.defaultEditors.put(File.class, new FileEditor());
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
this.defaultEditors.put(String[].class, new StringArrayPropertyEditor());
this.defaultEditors.put(URL.class, new URLEditor());
。。。。。。。
PropertyEditor的概念就是属性编辑器,或者说属性转换器,比如我们在spring的配置文件中设置某个bean的class,这是一个字符串,怎么转换为一个Class对象呢?通过上面注册的ClassEditor,看看这个类是怎么实现的:
<!---->public class ClassEditor extends PropertyEditorSupport {
private final ClassLoader classLoader;
/**
* Create a default ClassEditor, using the given ClassLoader.
* @param classLoader the ClassLoader to use
* (or <code>null</code> for the thread context ClassLoader)
*/
public ClassEditor(ClassLoader classLoader) {
this.classLoader =
(classLoader != null ? classLoader : Thread.currentThread().getContextClassLoader());
}
public void setAsText(String text) throws IllegalArgumentException {
if (StringUtils.hasText(text)) {
try {
//调用辅助类,得到Class对象
setValue(ClassUtils.forName(text.trim(), this.classLoader));
}
catch (ClassNotFoundException ex) {
throw new IllegalArgumentException("Class not found: " + ex.getMessage());
}
}
else {
setValue(null);
}
}
public String getAsText() {
Class clazz = (Class) getValue();
if (clazz == null) {
return "";
}
if (clazz.isArray()) {
return clazz.getComponentType().getName() + ClassUtils.ARRAY_SUFFIX;
}
else {
return clazz.getName();
}
}
}
代码已经解释了一切,继承javabean的PropertyEditorSupport,自己实现转换即可。这个包另外就是定义了一个完整的异常体系,值的我们参考。另外一个值的注意的地方是CachedIntrospectionResults类的实现,这个类使用了单例模式,它的作用在于缓存JavaBean反省(Introspect)得到的信息,因为每次使用Introspector对获取JavaBean信息是个不小的性能开支。缓存使用的是WeakHashMap,而不是HashMap,看看spring的解释:
<!---->/**
* Map keyed by class containing CachedIntrospectionResults.
* Needs to be a WeakHashMap with WeakReferences as values to allow
* for proper garbage collection in case of multiple class loaders.
*/
private static final Map classCache = Collections.synchronizedMap(new WeakHashMap());
因为缓存使用的key是bean的Class对象(以保证唯一性),因此在应用存在多个class loaders的时候,为了保证垃圾收集的进行,不出现内存泄露而采用WeakHashMap,为了理解这一点,我用JProfiler测试了自定义ClassLoader情况下,内存堆的使用情况,从快照上看。在使用HashMap的情况下,因为测试的bean的Class对象被载入它的ClassLoader以及java.beans.BeanInfo,java.beans.PropertyDescriptor,java.lang.reflect.Method这四个对象强引用,而导致不可回收。而在使用WeakHashMap时,判断当载入bean的ClassLoader和载入CachedIntrospectionResults的ClassLoader是不同的时候,使用弱引用包装缓存对象,保证能被回收。请看:
不知道我的理解是否有误,如果有误,请不吝指出,谢谢。
分享到:
相关推荐
DI 可以通过构造器注入、设值注入或接口注入实现,源码中可以看到`org.springframework.beans`和`org.springframework.context`包下相关的类和接口,如`BeanFactory`、`ApplicationContext`等。 2. **面向切面编程...
- **org.springframework.beans-3.1.0.M2.jar**:基础的Bean工厂实现。 - **org.springframework.context-3.1.0.M2.jar**:提供了上下文支持,扩展了Bean工厂功能。 - **org.springframework.jdbc-3.1.0.M2.jar**:...
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> ``` 这部分定义了Spring的命名空间,其中`xmlns`属性指定的是Spring ...
1. BeanFactory与ApplicationContext:在`org.springframework.beans.factory`包下,BeanFactory接口定义了基本的IoC功能,而ApplicationContext接口扩展了更多企业级服务,如消息支持、国际化等。`...
在源代码中,`org.springframework.beans.factory.BeanFactory` 和 `org.springframework.context.ApplicationContext` 是IoC容器的两个主要接口,它们提供了加载配置、获取Bean和处理依赖注入等功能。通过阅读这些...
Spring Framework 4.1.0是一款流行的Java平台上的开源框架,用于构建和维护可信赖、高效的企业级应用。本文会详细解读其参考文档中的主要知识点。 **一、Spring Framework概述** 1. Spring框架的入门 Spring框架...
- **`http://www.springframework.org/schema/beans/spring-beans.xsd`**:定义了核心Bean配置的Schema文件。 - **`http://www.springframework.org/schema/context/spring-context.xsd`**:定义了上下文配置的...
http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ...
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> ``` 这部分定义了XML文件的基本属性,包括版本号、编码格式等。`xmlns`指定...
"http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- 建立数据源 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 数据库驱动,这里使用的是MySQL数据库 -...
需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...
可以重点关注`org.springframework`包下的类,如`BeanFactory`、`ApplicationContext`、`AopProxy`等,它们是Spring的核心组件。 7. **源码分析** - `BeanFactory`是Spring的核心接口,它负责管理Bean的生命周期和...
本文将深入解析一个与Spring框架相关的错误:“火狐报错事项”,具体错误信息为:`org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from classpath resource ...
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userBean" class="com.bean.UserBean"> 张三"/> <bean id="userService" class="com.service.impl.UserServiceImpl"> ...
DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">` 定义了该文档遵循的DTD(Document Type Definition)类型。这里指定使用Spring的DTD,确保了文档格式...
《深入解析Spring Framework 3.2.10.RELEASE源码》 Spring Framework作为Java开发中的核心框架,其设计理念和实现细节一直以来都是开发者们热衷探索的领域。本篇文章将聚焦于Spring 3.2.10.RELEASE版本,通过源码...
- `xmlns="http://www.springframework.org/schema/beans"`:声明了Spring的Beans命名空间。 - `xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"`:定义了XSI命名空间,用于验证XML文档。 - `xmlns:p=...
<filter-class>org.springframework.web.filter.CharacterEncodingFilter <param-name>encoding <param-value>utf-8 <param-name>forceEncoding <param-value>true ``` 这里配置了一个字符编码过滤器...
在压缩包文件“Spring src”中,我们通常会找到Spring框架各模块的源代码,这些代码可能是按照模块划分的,如spring-core、spring-beans、spring-context、spring-web等。通过阅读源码,我们可以了解: 1. **依赖...