`

org.springframework.beans简单解读

阅读更多
    这个包的说明是说主要是包括用于操作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.classnew ClassEditor());
        
this.defaultEditors.put(File.classnew FileEditor());
        
this.defaultEditors.put(InputStream.classnew InputStreamEditor());
        
this.defaultEditors.put(Locale.classnew LocaleEditor());
        
this.defaultEditors.put(Properties.classnew PropertiesEditor());
        
this.defaultEditors.put(Resource[].classnew ResourceArrayPropertyEditor());
        
this.defaultEditors.put(String[].classnew StringArrayPropertyEditor());
        
this.defaultEditors.put(URL.classnew 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是不同的时候,使用弱引用包装缓存对象,保证能被回收。请看:
<!---->private static boolean isCacheSafe(Class clazz) {
        
//CachedIntrospectionResults的ClassLoader
        ClassLoader cur = CachedIntrospectionResults.class.getClassLoader();
        
//载入bean的ClassLoader
        ClassLoader target = clazz.getClassLoader();
        
if (target == null || cur == target) {
            
return true;
        }
        
while (cur != null) {
            cur 
= cur.getParent();
            
if (cur == target) {
                
return true;
            }
        }
        
return false;
    }

public static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {

   
   
boolean cacheSafe = isCacheSafe(beanClass);
   
if (cacheSafe) {
                classCache.put(beanClass, results);
            }
            
else {
           //弱引用   
            classCache.put(beanClass, new WeakReference(results));

            }
   

    不知道我的理解是否有误,如果有误,请不吝指出,谢谢。



dennis 2007-04-16 10:23 发表评论
分享到:
评论

相关推荐

    spring 源码

    DI 可以通过构造器注入、设值注入或接口注入实现,源码中可以看到`org.springframework.beans`和`org.springframework.context`包下相关的类和接口,如`BeanFactory`、`ApplicationContext`等。 2. **面向切面编程...

    SSH整合包详解.Struts2.2.3+Spring3.1.0.M2+Hibernate3.6.6

    - **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**:...

    Spring之AOP配置文件详解

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"&gt; ``` 这部分定义了Spring的命名空间,其中`xmlns`属性指定的是Spring ...

    spring-framework-4.2.3.RELEASE 源码

    1. BeanFactory与ApplicationContext:在`org.springframework.beans.factory`包下,BeanFactory接口定义了基本的IoC功能,而ApplicationContext接口扩展了更多企业级服务,如消息支持、国际化等。`...

    Spring框架核心源代码的分析及其感受-6

    在源代码中,`org.springframework.beans.factory.BeanFactory` 和 `org.springframework.context.ApplicationContext` 是IoC容器的两个主要接口,它们提供了加载配置、获取Bean和处理依赖注入等功能。通过阅读这些...

    Spring Framework 4.1.0参考文档

    Spring Framework 4.1.0是一款流行的Java平台上的开源框架,用于构建和维护可信赖、高效的企业级应用。本文会详细解读其参考文档中的主要知识点。 **一、Spring Framework概述** 1. Spring框架的入门 Spring框架...

    Springmvc最全约束配置文件

    - **`http://www.springframework.org/schema/beans/spring-beans.xsd`**:定义了核心Bean配置的Schema文件。 - **`http://www.springframework.org/schema/context/spring-context.xsd`**:定义了上下文配置的...

    springmvc+mybatis+oracle

    http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd ...

    spring框架配置bean的高级属性

    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"&gt; ``` 这部分定义了XML文件的基本属性,包括版本号、编码格式等。`xmlns`指定...

    spring配置文件说明.doc

    "http://www.springframework.org/dtd/spring-beans.dtd"&gt; &lt;beans&gt; &lt;!-- 建立数据源 --&gt; &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"&gt; &lt;!-- 数据库驱动,这里使用的是MySQL数据库 -...

    ssh(structs,spring,hibernate)框架中的上传下载

     需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...

    spring-framework-4.3.12.RELEASE--编译好的源码.rar

    可以重点关注`org.springframework`包下的类,如`BeanFactory`、`ApplicationContext`、`AopProxy`等,它们是Spring的核心组件。 7. **源码分析** - `BeanFactory`是Spring的核心接口,它负责管理Bean的生命周期和...

    火狐报错事项

    本文将深入解析一个与Spring框架相关的错误:“火狐报错事项”,具体错误信息为:`org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from classpath resource ...

    Spring IoC实现

    http://www.springframework.org/schema/beans/spring-beans.xsd"&gt; &lt;bean id="userBean" class="com.bean.UserBean"&gt; 张三"/&gt; &lt;bean id="userService" class="com.service.impl.UserServiceImpl"&gt; ...

    spring配置详解

    DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"&gt;` 定义了该文档遵循的DTD(Document Type Definition)类型。这里指定使用Spring的DTD,确保了文档格式...

    spring-framework-3.2.10.RELEASE 源码

    《深入解析Spring Framework 3.2.10.RELEASE源码》 Spring Framework作为Java开发中的核心框架,其设计理念和实现细节一直以来都是开发者们热衷探索的领域。本篇文章将聚焦于Spring 3.2.10.RELEASE版本,通过源码...

    mybatis plus.txt

    - `xmlns="http://www.springframework.org/schema/beans"`:声明了Spring的Beans命名空间。 - `xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"`:定义了XSI命名空间,用于验证XML文档。 - `xmlns:p=...

    struts1+spring+hibernate整合示例

    &lt;filter-class&gt;org.springframework.web.filter.CharacterEncodingFilter &lt;param-name&gt;encoding &lt;param-value&gt;utf-8 &lt;param-name&gt;forceEncoding &lt;param-value&gt;true ``` 这里配置了一个字符编码过滤器...

    Spring Src

    在压缩包文件“Spring src”中,我们通常会找到Spring框架各模块的源代码,这些代码可能是按照模块划分的,如spring-core、spring-beans、spring-context、spring-web等。通过阅读源码,我们可以了解: 1. **依赖...

Global site tag (gtag.js) - Google Analytics