Spring之依赖配置详解

通过以上的学习,对spring容器和DI的概念应该比较清晰了,DI(依赖注入)作为spring的核心,spring当然提供了一套完善的机制来进行依赖注入。前篇文章从概念上介绍了依赖注入,本篇着重学习spring依赖注入的方法,这里主要采用xml的方式。

基本注入

构造器注入和设值注入是依赖注入的两种主要方式,spring对此有很完善的实现,下面首先以代码的形式进行简要的说明。

构造器注入

Spring容器通过调用bean的构造函数(可能带有几个参数,每个参数代表一个依赖)完成构造器注入。通过静态工厂方法和调用构造器及其类似,这里一并进行说明。

Spring中构造器依赖注入采用以下的形式,每个参数用bean标签的子标签  < constructor-arg >进行配置:

    <bean id="..." class="com.test.wdi.ExampleBean">
       <constructor-arg index="..." value="..." name="..." ref="..." type="..."></constructor-arg>
.. .. ..
    </bean>

Index:在构造函数中参数的位置,从0开始<constructor-arg >标签中的配置包含5个项,使用他们中的某些进行某个依赖的配置,简单的描述如下:

Value:参数值,通常是基本类型和 type或者index配合使用。

Name:构造函数中参数的名字

Ref:引用其他Spring管理的对象

Type:参数的类型,值为基本类型或者完全限定的类名。

基本Bean

下面采用代码加注释的形式分别对以上的配置项加以说明,引用的类库见以前的文章,首先是简单的代码结构截图:

Fruit

Apple、Banana是用来演示ref配置项的,只是一个简单的类,没有任何字段。Fruit包含一个Apple和一个Banana,其代码如下:

package com.test.wdi;

/**
* @date 2015-2-27
* @Description:此类主要是为了说明构造器注入的ref项,包含了基本的构造函数,静态工厂方法,和实例工厂方法
*/

public class Fruit {

    private Apple apple;

    private Banana banana;

    public Fruit() {
       super();
    }

    /**
    * 静态工厂方法
    */
    public static Fruit newInstance(Apple apple, Banana banana){
       return new Fruit(apple, banana);
    }

    /**
    * 实例工厂方法
    */
    public Fruit  newInstance1(Apple apple, Banana banana){
       return new Fruit(apple, banana);
    }

    /**
    * 传统带参构造函数
    */
    public Fruit(Apple apple, Banana banana) {
       super();
       this.apple = apple;
       this.banana = banana;
    }

    public Apple getApple() {
       return apple;
    }

    public void setApple(Apple apple) {
       this.apple = apple;
    }

    public Banana getBanana() {
       return banana;
    }

    public void setBanana(Banana banana) {
       this.banana = banana;
    }

    @Override
    public String toString() {
       return hashCode()+ "Fruit [apple=" + apple + ", banana=" + banana + "]";
    }

}

ExampleBean

ExampleBean是用来演示除ref之外的其他配置项的,它有连个基本类型的字段,其代码如下:

package com.test.wdi;

/**
* @date 2015-2-28
* @Description:此类用来说明构造器注入配置项中的 name index type value的,为了方便重写了toString方法
*/
public class ExampleBean {

    private int years;
    private String ultimateAnswer;

    private boolean test;

    public ExampleBean() {
       super();
    }

    /**
     * 构造函数2,和构造函数1一样具有两个参数,如果bean配置中不加入type的限制,
     * 将会有和预期不一致的结果
     */
    public ExampleBean(int years, boolean test) {
        this.years = years;
        this.test = test;
    }

    /**
     * 构造函数1
     */
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }

    @Override
    public String toString() {
       return "ExampleBean [years=" + years + ", ultimateAnswer=" + ultimateAnswer + ", test=" + test + "]";
    }

}

BeanXMl配置

Bean的配置,将依次说明<constructor-arg >标签中每个配置属性的简单用法和它们的组合。bean配置包含连个文件,allbean.xml是主配置文件,它通过import标签引入t1.xml,而t1.xml包含了所有的配置信息,且有详细的注释:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
    此配置文件是spring 元数据的配置文件,根标签为 beans标签。
    在这个标签下可以定义由Spring 管理的 bean,其定义形式如下被注释的地方所示:
    基本的配置包括一个容器全局唯一的字符串id,和一个完全限定的类名。

    但在这个例子中,有两个import标签,分别引入了另外两个 xml元数据配置文件。
    这么做的好处是,不同的 bean定义对应相应的程序体系架构。
  import标签导入的配置文件路径是相对路径,相对于当前文件。

  路径前面可以与斜杠,但不建议这么做。如下示例不推荐使用
      <import resource="/com/test/dao/dao.xml"/>

  类似../的路径也不推荐使用

     -->

    <!-- 测试spring依赖注入 -->
    <import resource="com/test/wdi/t1.xml"/>

</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 定义一个Apple Bean -->
    <bean id="a" class="com.test.wdi.Apple">
    </bean>
       <!-- 定义一个Banana Bean -->

    <bean id="b" class="com.test.wdi.Banana">
    </bean>
    <!--传统的构造函数注入,采用ref配置,引用spring管理的其他bean -->
    <bean id="f1" class="com.test.wdi.Fruit">
       <constructor-arg ref="a"></constructor-arg>
       <constructor-arg ref="b"></constructor-arg>
    </bean>

    <!--静态工厂方法注入,将调用Fruit 的静态方法 newInstance,   采用ref配置,引用spring管理的其他bean -->
    <bean id="f2" class="com.test.wdi.Fruit" factory-method="newInstance">
       <constructor-arg ref="a"></constructor-arg>
       <constructor-arg ref="b"></constructor-arg>
    </bean>
    <!--实例工厂方法注入,将调用对象 f2 的静态方法 newInstance,   采用ref配置,引用spring管理的其他bean -->
    <bean id="f3" factory-bean="f2" factory-method="newInstance1">
       <constructor-arg ref="a"></constructor-arg>
       <constructor-arg ref="b"></constructor-arg>
    </bean>

    <!--直接采用 value配置项,在没有模糊性的前提下,spring能直接把value转化为正确的类型,但这里存在模糊性,因为ExampleBean中存在两个具有两个参数的构造函数
      据测试,哪个构造函数在前,就会优先使用哪个构造函数,在不匹配的情况下,依次类推。
      下面两个配置第一个使用     public ExampleBean(int years, boolean test)
      第二个因为true1 不能转化为 bool类型,则使用构造函数
        public ExampleBean(int years, String ultimateAnswer)

        但是问题在于,假如第一个配置的初衷是把 ExampleBean.ultimateAnswer的值设为"true" ,那么就和预期不一样。

        接下来的配置来解决以上问题
    -->
    <bean id="exam1a" class="com.test.wdi.ExampleBean">
       <constructor-arg value="1111"></constructor-arg>
       <constructor-arg value="true"></constructor-arg>
    </bean>
    <bean id="exam1b" class="com.test.wdi.ExampleBean">
       <constructor-arg value="1111"></constructor-arg>
       <constructor-arg value="true1"></constructor-arg>
    </bean>

    <!--直接采用 value配置项,采用type进行限定,使用正确的构造器型 -->
    <bean id="exam2" class="com.test.wdi.ExampleBean">
       <constructor-arg type="int" value="1"></constructor-arg>
       <constructor-arg type="java.lang.String" value="true"></constructor-arg>
    </bean>
    <!--直接采用 value配置项,采用type进行限定,使用正确的构造器型  使用index,可以不按顺序-->
    <bean id="exam3" class="com.test.wdi.ExampleBean">
        <constructor-arg index="1" value="true" type="java.lang.String"></constructor-arg>
       <constructor-arg index="0" value="2"></constructor-arg>
    </bean>
    <!--直接采用 value配置项,采用name进行限定,使用正确的构造器型  使用index,可以不按顺序
    不过使用name 有一些限制,限制在于必须以debug的形式编译类,因为只有这样,才可以保留构造函数中参数的变量名。
    或者使用在构造函数中使用注解 @ConstructorProperties

    如下
        @ConstructorProperties({"years", "ultimateAnswer"})
      public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
    -->

    <bean id="exam4" class="com.test.wdi.ExampleBean">
        <constructor-arg name="ultimateAnswer" value="true" />
       <constructor-arg name="years" value="3" />
    </bean>
</beans>

测试程序

测试程序使用main函数,依次打印出来t1中定义的那些bean,代码如下:

package com.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Description:
 * 本示例例环境为eclipse
 */
public class TestMain {
    public static void main(String[] args) {
       /**
        * ApplicationContext代表spring容器,而ClassPathXmlApplicationContext是它的一个实现,它从类路径下读取相应的
        *  xml 元数据配置,并初始化容器。其中allbean.xml是相应的元数据配置
        */
       ApplicationContext context = new ClassPathXmlApplicationContext("allbean.xml");

       //依次打印对象
       System.out.println(context.getBean("f1"));
       System.out.println(context.getBean("f2"));
       System.out.println(context.getBean("f3"));

       System.out.println(context.getBean("exam1a"));
       System.out.println(context.getBean("exam1b"));

       System.out.println(context.getBean("exam2"));
       System.out.println(context.getBean("exam3"));
       System.out.println(context.getBean("exam4"));

    }

}

测试结果如下截图,均符合预期:

注:构造器注意需要注意循环依赖的问题。

设值注入

设值注入是spring容器在调用过无参构造函数或者无参工厂方法后,然后通过调用其setter方法进行依赖的注入。

Set注入比较简单,之前的文章spring容器和配置初识所举的例子就是setter注入。下面是一段xml配置极其说明:

<!-- 通过 setter 进行注入,spring首先调用无参的构造函数,然后分别调用其相应的set方法
       property 标签有三个属性 name  ref  和 value
       其中 name是将要被注入的属性的名称。
       ref 是引用被spring管理的对象

       value 是实际的值,被spring 根据属性的类型,转换为对应的值。
       此转换由propertyEditor进行,这里暂且不提,value的值也可以是 spring表达式 spel
    -->
    <bean id="f4" class="com.test.wdi.Banana" >
        <property name="apple" ref="a"></property>
        <property name="banana" ref="b"></property>
    </bean>

依赖注入实例

依赖有多种类型,包含基本类型(int、double、string等)和复杂类型(系统类和自定义的类),下面依次说明它们在注入过程中需要注意的问题。

设置注入和构造器注入对应的标签分别是<property> 和<constructor-arg>它们的子标签的意义保持一致,下面的例子一般情况下,只做其中一种的说明。另外它们的属性除了 <constructor-arg> 单独拥有的type和 index 其他的也保持一致的意义。

直接类型(原始类型、字符串等)

直接类型直接使用value子标签或者属性配置即可。Spring的conversion service 会自动把字符串转化为真正的属性(属性或者构造函数参数)。

对应设置注入,由javabean规范和name属性可以准确的确定类型,故转换不存在问题。但是对于构造器注入,如果不对type或者name进行限制,可能会产生非预期结果。

如下一段配置实是上文中构造器中的一个片段,另外增加了设置注入加以比较。运行结果可以自行测试:

<!--直接采用 value配置项,在没有模糊性的前提下,spring能直接把value转化为正确的类型,但这里存在模糊性,因为ExampleBean中存在两个具有两个参数的构造函数
       据测试,哪个构造函数在前,就会优先使用哪个构造函数,在不匹配的情况下,依次类推。下面两个配置第一个使用 public ExampleBean(int
       years, boolean test) 第二个因为true1 不能转化为 bool类型,则使用构造函数 public ExampleBean(int
       years, String ultimateAnswer) 但是问题在于,假如第一个配置的初衷是把 ExampleBean.ultimateAnswer的
       值设为"true" ,那么就和预期不一样。解决的办法是加入type属性的限定,不要只使用参数的个数(对于基本类型会有模糊性) -->

    <bean id="exam1a" class="com.test.wdi.ExampleBean">
       <constructor-arg value="1111"></constructor-arg>
       <constructor-arg value="true"></constructor-arg>
    </bean>
    <bean id="exam1b" class="com.test.wdi.ExampleBean">
       <constructor-arg value="1111"></constructor-arg>
       <constructor-arg value="true1"></constructor-arg>
    </bean>
    <!-- 设值注入有name 可以确定需要转换的类型 -->

    <bean id="exam1c" class="com.test.wdi.ExampleBean">
       <property name="years" value="1111"></property>
       <property name="ultimateAnswer" value="true1"></property>
       <property name="test" value="true"></property>
    </bean>

另外类型为java.util.properties可以采用类似下面的配置:

<bean id="mappings"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

    <!-- typed as a java.util.Properties -->
    <property name="properties">
        <value>
            jdbc.driver.className=com.mysql.jdbc.Driver
            jdbc.url=jdbc:mysql://localhost:3306/mydb
        </value>
    </property>
</bean>

Idref标签

Idref子标签只是一个把某个bean的id传递作为依赖传递给另外一个bean的防止错误的方式。通过只传递bean的id,可以构建构建更加灵活的程序。

基本的配置如下:

<!-- 以下两个配置等价  ,这两个配置的初衷在于把  "exam1c" 这个bean id 作为依赖传递给另一个bean
    (在此例子中是传递给 id为 exam1d* 的bean ),从而构建更通用的方法。通用的方法比如说是直接从
    spring容器中通过id获取相应的对象,执行相应的方法。

    区别在于第一种方法 spring容器会验证id 或者name 为  exam1c 的bean在容器(当前容器或者父容器)中真的存在,如果不存在则会报出异常,及早发现,而第二种则不会,直道真正运行时才发现。
    -->
    <bean id="exam1d1" class="com.test.wdi.ExampleBean">
        <property name="years" value="1111"></property>
        <property name="ultimateAnswer" >
            <idref bean="exam1c"/></property>
        <property name="test" value="true"></property>
    </bean>
    <bean id="exam1d2" class="com.test.wdi.ExampleBean">
        <property name="years" value="1111"></property>
        <property name="ultimateAnswer" value="exam1c"> </property>
        <property name="test" value="true"></property>
    </bean>

引用其他bean

引用其他bean是spring中及其常见的场景,这种配置通过<constructor-arg/> 或<property/> 的子标签<ref>实现,或者通过ref属性(实质上是子标签的一种缩写)。而子标签的形式提供了更具体的用法和配置。

基本样式如下:

<ref
bean="someBean"/>

或者

<ref
parent="someBean"/>

以上两者的区别是:前者在当前spring容器和父容器中寻找id(name)为someBean
的对象,而后者只在父容器中寻找。

而ref属性是前者的简写。

下面看具体的例子:

<!-- 以下两种配置等同,不同点在于前者是使用标签配置,后者使用属性配置 -->
    <bean id="f5a" class="com.test.wdi.Fruit">
       <property name="apple">
           <ref bean="a" />
       </property>
       <property name="banana">
           <ref bean="b" />
       </property>
    </bean>
    <bean id="f5b" class="com.test.wdi.Fruit">
       <property name="apple" ref="a">
       </property>
       <property name="banana" ref="b"></property>
    </bean>

内部bean

在<constructor-arg/> 或<property/>内部定义的bean称之为内部bean,spring会自动忽略其id、name 属性和 scope属性,配置如下:

<!-- 内部bean  ,会自动忽略其id、name 属性和 scope属性-->
    <bean id="f5c" class="com.test.wdi.Fruit">
       <property name="apple">
           <bean id="idIgnore" class="com.test.wdi.Apple" ></bean>
       </property>
       <property name="banana">
           <bean class="com.test.wdi.Banana"></bean>

       </property>
    </bean>

集合

Java的强大之处之一在于jdk提供了强大的集合框架,spring当然提供了注入集合的方法。

自从java1.5开始,支持泛型,我们的集合尽量使用泛型,另外关于集合合并涉及到bean定义的继承,这里暂不讨论。

首先引入一个带集合属性的bean,省略了构造函数和get set方法。

public class FruitCollection {

    private Set<Fruit> fruits;
    private List<Fruit> fruitList;

    private Map<String, Fruit> fruitMap;

    private Properties ppp;
}

具体见下面的配置代码:

<!-- 集合的注入,包括 set list map properties -->
    <bean id="fruitSet" class="com.test.wdid.FruitCollection">
       <property name="fruits">
           <!-- 集合 set标签,可以定义内部bean,引用其他bean -->
           <set>
              <bean class="com.test.wdi.Fruit">
                  <property name="apple" ref="a">
                  </property>
                  <property name="banana" ref="b"></property>
              </bean>
              <ref bean="f1" />
              <ref bean="f2" />
              <ref bean="f3" />
              <ref bean="f4" />
              <ref bean="f5a" />
              <ref bean="f5b" />
              <ref bean="f5c" />
           </set>
       </property>

       <property name="fruitList">
                   <!--  list标签,可以定义内部bean,引用其他bean -->
           <list>
              <bean class="com.test.wdi.Fruit">
                  <property name="apple" ref="a">
                  </property>
                  <property name="banana" ref="b"></property>
              </bean>
              <ref bean="f1" />
              <ref bean="f2" />
              <ref bean="f3" />
              <ref bean="f4" />
              <ref bean="f5a" />
              <ref bean="f5b" />
              <ref bean="f5c" />
           </list>
       </property>

       <property name="fruitMap">
           <!--  map标签  定义enrty 子标签,属性有  key value key-ref value-ref ,意思很明显-->
           <map>
              <entry key="f1" value-ref="f1" ></entry>
              <entry key="f2" value-ref="f2"></entry>
              <entry key="f3" value-ref="f3"></entry>
              <entry key="f4" value-ref="f4"></entry>
           </map>
       </property>

       <property name="ppp">

           <!--  props标签  定义prop 子标签,本质是字符串类型的键值对-->

           <props>
              <prop key="1">t1</prop>
              <prop key="2">t2</prop>
              <prop key="3">t3</prop>
              <prop key="4">t4</prop>
           </props>
       </property>
    </bean>

Null和空串

Spring支持注入null和字符串的空串,见如下的配置:

<!-- 空串和null -->
    <bean id="exam5Null" class="com.test.wdi.ExampleBean">
        <property name="years" value="1111"></property>
       <property name="ultimateAnswer">
           <null/>
       </property>
       <property name="test" value="true"></property>
    </bean>

    <bean id="exam5Empty" class="com.test.wdi.ExampleBean">
         <property name="years" value="1111"></property>
       <property name="ultimateAnswer" value="">
       </property>
       <property name="test" value="true"></property>
    </bean>

实际相当于分别执行了如下方法:

setUltimateAnswer(null);
setUltimateAnswer("");

缩写

Spring的bean配置文件的格式除了以上用了多次的标准形式,还有一些简单的缩略形式,这些缩略形式是基于xml命名空间,分别是p-nameplace和c-nameplace,依次对应seter注入和 构造器注入。

这里不再赘述。直接贴一个spring官方文档的示例来说明p命名空间:

<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.xsd">

    <bean name="classic" class="com.example.ExampleBean">
        <property name="email" value="[email protected]"/>
    </bean>

    <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="[email protected]"/>
</beans>

复合属性名

嵌套的注入,fruit 有个apple属性,假设apple 有个 color属性。那么可以在fruit的定义中直接为color注入属性,前提是apple不为null:

    <!-- 缩写复合属性名  假设apple 有个 color属性 -->
    <bean id="fwithColor" class = "com.test.wdi.Fruit">
        <property name="apple" ref="a"></property>
        <property name="apple.color" value="yellow"></property>
    </bean>

结束

本文从spring两种依赖注入讲起,然后举出具体的配置例子依次讲解到了大部门的注入实例,本文中大部分的例子均通过测试,环境为spring4.1.5。但本人水平有限,肯定有很多不当和不完整支持,期待共同进步,本文中的实例用到的代码地址为:本文资源下载地址(免积分)

时间: 2024-08-29 13:18:30

Spring之依赖配置详解的相关文章

基于Spring Cloud的微服务构建学习-3 Spring Cloud Eureka配置详解

配置详解 在Eureka的服务治理体系中,主要分为服务端与客户端.服务端为服务注册中心,而客户端为各个提供接口的微服务应用.当部署高可用注册中心时,每个服务端也已经成为了客户端,因此,在使用Spring Cloud Eureka的过程中,我们所做的配置内容几乎都是对Eureka客户端配置进行的操作,所以了解这部分的配置内容,对于用好Eureka非常有帮助. 而Eureka服务端更多类似于一个现成产品,大多数情况下,我们不需要修改它的配置信息. Eureka客户端配置分类 服务注册相关配置,包括服

spring sessionFactory 属性配置详解,applicationContext中各种属性详解

1.Bean的id为sessionFactory,对应的类为AnnotationSessionFactory,即采用注解的形式实现hibernate. 2.hibernateProperties,配置hibernate的属性 1)hibernate.dialect,配置Hibernate方言,可以让Hibernate使用某些特定的数据库平台的特性,具体的dialect大全: 结下不同数据库的该属性的值如下表.其中属性值得格式:{hibernatejar的全名}.dialaect.{对应数据库}D

Spring之——c3p0配置详解

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51162560 今天,我们就来详细谈谈Spring中的c3p0配置问题,好了,不耽搁大家的时间,我们直接进入主题,请看下面的具体配置文件信息: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/

spring与shiro配置详解

1.加入shiro相关依赖的jar包 pom.xml部分内容如下: 1 <dependency> 2 <groupId>org.apache.shiro</groupId> 3 <artifactId>shiro-spring</artifactId> 4 <version>1.3.2</version> 5 </dependency> 6 <dependency> 7 <groupId>

spring+springMVC+JPA配置详解

SpringMVC是越来越火,自己也弄一个Spring+SpringMVC+JPA的简单框架. 1.搭建环境. 1)下载Spring3.1.2的发布包:Hibernate4.1.7的发布包(没有使用hibernate的API,只是使用了它对JPA的实现):下载 BoneCP 连接池框架及其依赖的jar,下载缓存框架ehcache,全部所用到的jar包如下: ? antlr-2.7.7.jar bonecp-0.7.1.RELEASE.jar bonecp-provider-0.7.1-rc2.j

Spring的datasource配置详解【转】

一句话,Spring对Hibernate的整合,是在applicationContext.xml中配置sessionFactory来实现的,其中sessionFactory中要装配dataSource.下面就详细介绍dataSource Bean的配置. SessionFactory接口负责初始化Hibernate.它充当数据存储源的代理,并负责创建Session对象.这里用到了工厂模式.需要注意的是SessionFactory并不是轻量级的,因为一般情况下,一个项目通常只需要一个Session

spring 定时任务参数配置详解

注:本文摘自<Quartz Cron 触发器 Cron Expression 的格式>http://blog.csdn.net/yefengmeander/article/details/5985064 非常感谢作者!!! Quartz Cron 表达式支持到七个域  :秒 分 时 日 月 周 年(顺序万不可乱!!!) 名称          是否必须             允许值                 特殊字符  秒                  是             

spring声明式事务配置详解

spring声明式事务配置详解 君子不器 2013年06月16日 编程世界 5273次阅读 查看评论 理解Spring的声明式事务管理实现 本节的目的是消除与使用声明式事务管理有关的神秘性.简单点儿总是好的,这份参考文档只是告诉你给你的类加上@Transactional注解,在配置文件中添加('<tx:annotation-driven/>')行,然后期望你理解整个过程是怎么工作的.此节讲述Spring的声明式事务管理内部的工作机制,以帮助你在面对事务相关的问题时不至于误入迷途,回朔到上游平静

Spring的配置详解

Spring的配置详解 3.1XML配置的结构 <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