欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring_2 博客分类: Spring spring配置信息bean 

程序员文章站 2024-03-22 08:33:22
...
Bean配置信息是Bean的元数据信息,它由4个方面组成:Bean的实现类、Bean的属性信息、Bean的依赖关系和Bean的行为配置。
Bean元数据信息在Spring容器中的内部对应是由一个个BeanDefinition形成的Bean注册表,Spring实现了Bean元数据信息内部表示和外部表示的解耦。Spring支持多种形式Bean的配置方式。Bean配置信息定义了Bean的实现及依赖关系,Sprign容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后讲这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。

基于XML的配置
采用基于Schema配置格式,文件头的声明会复杂一些。
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
</beans>

Schema在文档根节点中通过xmlns对文档中的命名空间进行声明。我们在上面的代码中定义了3个命名空间:
1.默认命名空间:没有空间名,用于Spring Bean的定义
2.xsi命名空间:这个命名空间用于为每个文档中命名空间指定相应的Schema样式文件,是标准组织定义的标准命名空间
3.aop命名空间:这个命名空间是Spring配置AOP的命名空间,是用户自定义的命名空间
命名空间的定义分为两个步骤:第一步指定命名空间的名称,第二步指定命名空间的Schema文档样式文件的位置,用空格或回车换行进行分隔

若命名空间的别名为空,则表示该命名空间为文档默认命名空间,文档中无命名空间前缀的元素都属于默认命名空间。
命名空间使用全限定名,每个组织机构在发布Schema文件后,都会为该Schema文件提供一个引用的URL地址,一般使用这个URL地址指定命名空间对应的Schema文件。命名空间名称和对应的Schema文件地址之间使用空格或回车分隔,不同的命名空间之间也使用这种分隔方法。

Bean的命名:在配置一个Bean时,需要为其指定一个id属性作为Bean的名称。id在IoC容器中必须是唯一的,此外id的命名需要满足XML对id的命名规范:必须以字母开始、后面可以是字母、数字、连字符、下划线、句号、冒号等完整结束符,逗号和空格这些非完整结束符是非法的。
Spring配置文件不允许出现两个相同id的<bean>,但却可以出现两个相同name的<bean>,若出现多个相同name的<bean>,通过getBean(beanName)时,返回最后声明的那个Bean。

属性注入要求bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。若在类中显式定义了一个带参的构造函数,则需要同时提供一个默认的构造函数。Spring只会检查Bean中是否有对应的setter方法,只有Bean中是否有对应的属性变量则不做要求。

JavaBean关于属性命名的特殊规范:JavaBean的属性变量名都以小写字母起头,但也允许大写字母开头的属性变量名,但必须满足变量的前两个字母要么全大写,要么全小写。

使用构造函数注入的前提是Bean必须提供带参的构造函数。
//通过类型匹配参数
public class Car{
    public Car(String brand,double price){
         this.brand=brand;
         this.price=price;
    }
}
<bean id="car" class="com.Car">
    <constructor-arg type="java.lang.String">
          <value>CA72</value>
   </construtor-arg>
   <constructor-arg type="double">
          <value>20000</value>
   </construtor-arg>
</bean>

//通过索引匹配参数
public class Car{
    public Car(String brand,String corp,double price){
         this.brand=brand;
         this.corp=corp;
         this.price=price;
    }
}
<bean id="car" class="com.Car">
    <constructor-arg index="0" value="CA72"  />
    <constructor-arg index="1" value="CHINA"  />
    <constructor-arg index="2" value=20000  />
</bean>

//通过使用索引和类型匹配参数
public class Car{
    public Car(String brand,String corp,double price){
         this.brand=brand;
         this.corp=corp;
         this.price=price;
    }
}
public class Car{
    public Car(String brand,String corp,int price){
         this.brand=brand;
         this.corp=corp;
         this.price=price;
    }
}
<bean id="car" class="com.Car">
    <constructor-arg index="0" type="java.lang.String">
          <value>CA72</value>
   </construtor-arg>
   <constructor-arg index="1" type="java.lang.String">
          <value>CHINA</value>
   </construtor-arg>
   <constructor-arg index="2" type="double">
          <value>20000</value>
   </construtor-arg>
</bean>

通过自身类型反射匹配入参:若Bean构造函数入参的类型是可辨别的,即使构造函数注入配置不提供类型和索引信息,Spring依旧可以正确地完成构造函数的注入工作。

XML共有5个特殊的字符,若配置文件中的注入值包括这些特殊字符,需要进行特别处理。
                            XML特殊实体符号
特殊符号         转义序列          特殊符号          转义序列
   <                &lt               "                 &quot
   >                &gt               '                 &apos
   &                &amp

<ref>可以通过一下三个属性引用容器中其他Bean
bean:通过该属性可以引用同一容器或父容器的Bean
local:通过该属性只能引用同一配置文件中定义的Bean,它可以利用XML解析器自动检验引用的合法性,以便在开发编写配置时能够及时发现并纠正配置的错误。
parent:引用父容器中的Bean

Spring使用跟一个专用的<null/>元素标签作为null值。

<list>                                       
   <value></value>
   <value></value>
</list>

<set>  
   <value></value>
   <value></value>
</set>

<map>
   <entry>
         <key><value></value></key>
         <value></value>
   </entry>
   <entry>
         <key><value></value></key>
         <value></value>
   </entry>
</map>

<property>
    <props>
       <prop key=""></pro>
       <prop key=""></pro>
    </props>
</property>

集合合并:允许子<bean>继承父<bean>的同名属性集合元素,并将子<bean>中配置的结合属性值和父<bean>中配置的同名属性值合并起来作为最终的bean值。
<bean id="parentBoss"  abstract-"true"  class="Boss">
    <property name="favorites">
       <set>  
           <value>Read</value>
           <value>Run</value>
       </set>    
    </property>
</bean>
<bean id="childBoss"  parent="parentBoss">
    <property name="favorites">
       <set merge="true">  
           <value>Swim</value>
           <value>Sing</value>
       </set>    
    </property>
</bean>

若需配置一个集合类型的Bean,为非一个集合类型的属性,可以通过util命名空间进行配置。
<util:list id="" list-class="">
      <value>Swim</value>
      <value>Sing</value>
</util:list>

为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。
例:使用p明明空间
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  <bean id="car"  class=""
      p:brand=""
      p:maxSpeed=""
   />
</beans>

<bean>元素提供改了一个指定自动装配类型的属性:autowire="<自动装配类型>"。Spring提供了4种自动装配类型。
byName:根据名称进行自动匹配
byType:根据类型进行自动匹配
constructor:与ByType类似,只不是针对构造函数注入而言
autodetect:根据Bean的自省机制决定采用byType还是constructor进行自动装配

lookup方法注入
public interface MagicBoss{
   Car getCar();
}

<bean id="car" class="Car"
    p:brand=""
    p:price=""
    scope="prototype"
/>
<bean id="magicBoss" class="MagicBoss">
     <lookup-method name="getCar"  bean="car" />
</bean>

方法替换
用于替换他人的bean必须实现MethodReplacer接口,Spring将利用该接口方法去替换目标Bean的方法。
public class Boss1{
   public Car getCar(){
       Car car = new Car();
       car.setBrand("BMWZ4");
       return car;
   }
}

public class Boss2 implements MethodReplacer{
    public Object reimplement(Object arg0,Method arg1,Object[] arg2) throws Throwable{
       Car car =  new Car();
       car.setBrand("BENZ");
       return car;
    }
}

<bean id="boss1" class="Boss1">
   <replace-method name="getCar" replacer="boss2" />
</bean>
<bean id="boss2" class="Boss2"   />

bean之间的关系有继承、依赖和引用。
继承:父<bean>的主要功能是简化子<bean>的配置。一般都将父<bean>设为abstract类,表示为这个<bean>不实例化为对应的Bean。
<bean id="abstractCar" class="Car"
     p:brand="BMWZ4"
     p:maxSpeed=250
     abstract="true"
/>
<bean id="Car1" parent="abstractCar" p:color="red"  />
<bean id="Car2" parent="abstractCar" p:color="black"  />

依赖:使用<ref>元素标签建立对其他bean的依赖关系,Spring负责管理这些Bean的关系,当实例化一个Bean时,Spring保证该Bean所依赖的其他Bean已经初始化。Spring允许用户通过depends-on属性指定Bean前置依赖的Bean,前置依赖的Bean会在本Bean实例化之前创建好。

public class SystemSettings{
     public static int SESSION_TIMEOUT=30;
     public static int REFRESH_CYCLE=60;
}

public class SysInit{
   public SysInit(){
       SystemSettings.SESSION_TIMEOUT=10;
       SystemSettings.REFRESH_CYCLE=100;
   }
}

public class CacheManager{
   public CacheManager(){
      Timer timer = new Timer();
      TimerTash cacheTask = new CacheTask();
      timer.schedule(cacheTask,0,SystemSettings.REFRESH?_CYCLE);
   }
}

<bean id="manager"  class="CacheManager" depends-on="sysInit"  />
<bean id="sysInit" class="SysInit" />

引用:Spring提供了一个<idref>标签,通过<idref>引用跟另一个<bean>的名字
<bean id="car"  class="Car">
<bean id="boss" class="Boss">
   <property name="carId">
        <idref bean="car"  />
   </property>
</bean>

整合多个配置文件:Spring允许我们通过<import>将多个配置文件引入到一个文件中,进行配置文件的集成。
<import resource="classpath:com/beans1.xml">

                          Bean的作用域类型
类别                                   说明
singleton      在Sprign IoC容器中仅存在一个Bean实例,Bean以单实例的方式存在
prototype      每次从容器中调用Bean时,都返回一个新的实例
request        每次HTTP Session请求都会创建一个新的Bean,仅适用于WebApplicationContxt环境
session        同一个HTTP Session共享一个Bean,不同HTTP Session使用不同的Bean,仅适用于WebApplicationContxt环境
globalSession  同一个全局Session共享一个Bean,一般用于porlet应用环境,仅适用于WebApplicationContxt环境

Spring还允许用户自定义Bean的作用域,可以通过org.springframework.beans.factory.config.Scope接口定义新的作用域,再通过org.springframeworl.beans.factory.config.CustomScopeConfigure总金额个BeanFactoryPostProcessor注册自定义的Bean作用域。

singleton作用域
无状态或状态不可变的类适合使用单实例模式。在Spring环境下,对于所有的Dao类都可以采用单实例模式。在默认情况下,Spring的ApplicationContext容器在启动时,自动实例化所有singleton的Bean并缓存于容器中。虽然在启动时会花费一些时间,但带来两个好处:首先对Bean提前的实例化操作会及早发现一些潜在的配置问题;其次Bean以缓存的方式保存,当运行期使用到该Bean时就无须再实例化了,加快了运行效率。若用户不希望在容器启动时提前实例化singleton的Bean,可以通过lazy-init属性进行控制:
<bean id="boss1" class="Boss" lazy-init="true" />

prototype作用域:采用scope="prototype"指定非单实例作用域的Bean。在默认的情况下,Spring容器在启动时不实例化prototype的Bean。此外,Spring容器将prototype的Bean交给调用者,就不再管理它的生命周期了。

Web应用环境相关的Bean作用域
若用户使用Spring的WebApplicationContext,则还可使用另外3种Bean的作用域:request、session和globalSession。不过使用这些作用域之前,首先必须在Web容器中进行一些额外的配置。
在Web容器中进行额外的配置
在低版本的Web容器中,用户可以使用HTTP请求过滤器进行配置
<web-app>
    ...
    <filter>
         <filter-name>requestContextFilter</filter-name>
         <filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
    </filter>
    <filter-mapping>
         <filter-name>requestContextFilter</filter-name>
         <url-pattern>/*</url-pattern>
    </filter-mapping>
    ...
</web-app>
在高版本的Web容器中,则可以利用HTTP请求监听器进行配置
<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
   ...
</web-app>