Spring框架Bean配置纯XML文件方案详解

with 0 comment

Spring框架的核心就是依赖注入特性对实例Bean进行管理,最古老最经典最基础的Bean配置方案就是纯XML配置,结构清晰明了,适合大型项目使用。

Spring7.jpg

bean配置

Spring的Bean配置的方式有很多种,具体有三:JAVA配置、注解配置、XML配置
三种配置类型之间往往是等效的,实际应用中采用哪种方案则仁者见仁
本文主要针对纯粹的XML文件配置模式进行详解,个人比较喜欢用这种配置方法,更具有考证性,关系明显,条理清晰
缺点:需要写业务层和控制层需要写get和set方法进行注入,关系引用如果漏配比较令人暴躁

指定配置文件

无论使用那种配置方式都需要指定关键配置文件。
在web.xml指向自定义的配置文件名:mebugs.service.xml
ContextLoaderListener是Spring的监听器,它的作用就是启动Web容器时,自动装配ApplicationContext的配置信息
因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!-- classpath是指 WEB-INF文件夹下的classes目录 -->
    <!-- classpath 和 classpath* 区别 -->
    <!-- classpath:只会到你的class路径中查找找文件 -->
    <!-- classpath*:不仅包含class路径,还包括jar文件中(class路径)进行查找 -->
    <!-- <param-value>classpath:mebugs.service.xml </param-value> -->
    <!-- 可以加载多个文件 -->
    <param-value>
        /WEB-INF/classes/mebugs.service.xml
    </param-value>
</context-param>

配置文件结构

xmlns是XML Namespace 的缩写,这里表示spring 命名空间。
Spring在Classpath中查找所有的 spring.handlers 并解析xml配置的命名空间与对应的处理类。
命名空间的这些项目不是固定的,可从 http://www.springframework.org/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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
...
</beans>

Bean配置基础标签

Bean配置标签是放在上方beans标签内
有多种方式可以配置一个Bean实例,见实例

<!-- 指定id,唯一标识,最常用的方案 -->
<!-- getBean("user",User.class); -->
<bean id="user" class="com.mebugs.uesr.bean.User"></bean>
<!-- 不指定id,只配置必须的全限定类名,由IoC容器为其生成一个标识 -->
<!-- 程序通过getBean(User.class);获取Bean -->
<bean class="com.mebugs.uesr.bean.User"></bean>
<!-- 指定name,唯一标识 -->
<!-- 程序通过getBean("user",User.class);获取Bean -->
<bean name="user" class="com.mebugs.uesr.bean.User"></bean>
<!-- 指定别名,一个bean可以多个别名 -->
<!-- 程序通过getBean("sir",User.class);获取Bean -->
<bean name="user" alias="sir" class="com.mebugs.uesr.bean.User"></bean>
<!-- 同时指定了id和name,id就是标识符,而name就是别名 -->
<!-- 同时指定多个name,第一个被用作标识符,其他的是别名 -->

name或id都作为标识符,那为什么还要同时存在呢?
注意:
使用基于XML的配置元数据时,在XML中id是一个真正的XML id属性,可以利用XML解析器来验证引用的这个id是否存在,从而更早的发现是否引用了一个不存在的Bean
使用name,则可能要在真正使用bean时才能发现引用一个不存在的Bean
这也是为什么,使用id是最常见的配置方案,让错误暴露在前!

Bean配置标签属性

下面来了解一下bean配置的标签属性,这将有助于我们更好的配置Bean实例。
以下参数均是按需使用,不配置则表示默认值

depends-on

parent

scope

singleton

autowire

dependency-check

abstract

lazy-init

init-method

destroy-method

factory-bean

factory-method

Bean配置参数注入

Bean配置的参数注入有多种,最常见的是属性注入,此外还有构造注入和工厂注入,一一了解一下吧。
注入的值有特殊字符如”<>“,使用<![CDATA[]]> 包起来

属性注入

我们在实际应用中参数注入绝大多数时候不会放在XML配置文件中写死参数。

<bean id="user" class="com.mebugs.uesr.bean.User">
    <!-- 常规属性注入,利用的是setter方法,如下方的setName() -->
    <property name="name" value="lily"></property>
    <!-- 对象型属性注入,ref指向bean-id,如下方的userExtInfo -->
    <property name="extInfo" ref="userExtInfo"></property>
    <!-- 注入map集合,如成绩 -->
    <property name="scoreMap">
        <map key-type="java.lang.String" value-type="java.lang.Integer">
            <entry key="语文" value="60"></entry>
            <entry key="数学" value="60"></entry>
        </map>
    </property>
    <!-- 注入list,如关系,家庭与同事 -->
    <property name="relationList">
        <list>
            <ref bean="family"/>
            <ref bean="colleague"/>
        </list>
    </property>
    <!-- 其他 -->
</bean>

拓展 p 命名空间

<bean id="user" p:name="lily" p:age="30" class="com.mebugs.uesr.bean.User">
</bean>

构造注入

将配置的参数注入到构造函数中去。

<bean id="user" class="com.mebugs.uesr.bean.User">
    <!-- index构造参数的顺序 -->
    <constructor-arg index="0" value="lily"></constructor-arg>
    <!-- value构造参数的值 -->
    <constructor-arg index="1" value="same"></constructor-arg>
    <!-- type构造参数的类型,也可使用type="java.lang.String" -->
    <constructor-arg index="2" value="2002" type="double"></constructor-arg>
</bean>

工厂注入

使用较少,了解即可

<!-- factory-bean建该Bean对象的工厂类,使用了则class属性失效 -->
<!-- factory-method创建该Bean对象的工厂方法,与factory-bean关联 -->
<!-- factory-method单纯的指定工厂方法是需要指定class的 -->
<bean id="docFactory" class="com.mebugs.factory.DocFactory"></bean>
<bean id="doctor" factory-method="makeDoc" factory-bean="docFactory">
    <!-- 静态工厂方法需要传入参数,则使用constructor-arg来配置参数 -->
    <constructor-arg value="lily"></constructor-arg>
</bean>
Responses