Spring配置Bean的属性和依赖关系

Spring的IOC容器负责管理所有的应用系统组件,并协助组件之间建立关联。

Spring支持Properties文件格式,和XML文件配置,XML是常用的。

设置普通属性值(设值注入)

当bean实例创建以后,Spring会遍历配置文件的<bean>元素中所有的<property>子元素,每发现一个<property>,就根据name属性调用相应的setter方法

用反射来理解的话,代码如下:

容器初始化时

//反射创建实例
Class target = Class.forName("com.spring.bean.Animal");
Object bean = target.newInstance();

//初始化容器时,调用setter注入
String _setName = "set" + name属性值;
Method setMethod = target.getMethod(setName,Arthur.getClass());
setMethod.invoke(bean,Arthur);

用内省理解的话,差别在于获取setter方法

//反射创建实例
Class target = Class.forName("com.spring.bean.Animal");
Object bean = target.newInstance();

BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();

Method setter = null;

if(pds!=null){
    for(PropertyDescriptor pd : pds) {
        String fieldName = pd.getName();
        if(fieldName.equals('<property>的name属性值')){
            setter = fieldName.getMethodDescriptor();
        }
    }
}

setter.invoke(bean,'ref的对象');
设置合作Bean

<property>的ref设置,可参看Spring记录之IOC模拟

注入集合

Spring通过<list><map><set>或<props>分别表示List,Map,Set,Properties对象,然后,向其传入任何可用于注入的其他类型的独立元素,向给普通的<property>标签配置属性一样

  • List和数组类型,用<list>
  • 保持集合数据唯一,不重复,用Set集合
  • Map类型,用,子元素用<entry>,子元素包括<key>和<value>;<entry>的<value>子元素根上述两种一样,<key>只能是String
  • Properties集合用<prop>元素配置,Properties的key和value只能是String类型。<property><props><prop key="aa">bb</prop></props></property>

Spring管理Bean的生命周期

Spring 3.0之后又5种作用域 - Singleton: 单例,不解释 - Prototype: 原型模式,每次从容器获取Bean时,创建一个新的实例 - Request: 针对每次Http请求,产生一个新的Bean实例,其仅当前request有效 - Session: 同上,仅当前session有效 - Global session: 类似上述Session,但仅仅基于portlet的web应用才有效


  • scope为singleton Spring可以管理scope为singleton的Bean的生命周期,Spring可以精确知道Bean何时创建,何时初始化完成,何时被销毁。
  • scope为prototype Spring仅仅负责创建,scope为prototype的Bean不会注入容器,实例创建后,实例完全交给客户端代码管理。

对于上述的作用域,可参看Spring记录之IOC模拟

有两个生命周期时间点与Bean关系尤为重要

  • psotinitiation 初始化后
  • predestruciton 销毁前

Spring提供两种机制,并执行一些附加的基于interface或method的处理

  • 基于接口
  • Spring广泛运用基于接口的机制。
  • 如果不太关注移植性,或者定义了许多需要用到生命周期通知的同类型Bean,使用接口可确保Bean总能收到通知,代码更简洁
  • 基于方法
  • 如果注重移植性,或指定一两个需要回调的特定类型的Bean,使用基于方法机制

这当中有些重要的接口可以让Bean继承或实现 - BeanNameAware,setBeanName(String id)方法获得Bean自己的名字 - BeanFactoryAware,setBeanFactoryAware()获取容器引用 - ApplicationContextAware,setApplicationContext()获取容器引用 - BeanPostProcessor,postProcessAfterInitialization() - InitializingBean,afterPropertiesSet()Bean初始化后执行,但该接口是侵入式设计 - init-method属性指定初始化方法 - BeanPostProcessor,postProcessAfterInitialization() - DisposableBean,destory()方法 - destory-method属性指定销毁Bean的方法