01_Spring_快速入门

一. Spring概述

1.1 什么是Spring

Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE (一栈式) 轻量级开源框架。

  • JEE分层
    • 表现层(页面数据显示、页面跳转调度)jsp/servlet
    • 业务层(业务处理和功能逻辑、事务控制)-service
    • 持久层(数据存取和封装、和数据库打交道)dao
  • 一站式

    Spring提供了JavaEE各层的解决方案:
        表现层:Spring MVC,持久层:JdbcTemplate、ORM框架整合,业务层:IoC、AOP、事务控制。
  • 轻量级:Spring的出现取代了EJB的臃肿、低效、繁琐复杂、脱离现实。

1.2 Spring的核心

IoC(Inverse of Control 反转控制): 将对象创建权利交给Spring工厂进行管理。

AOP(Aspect Oriented Programming 面向切面编程),基于动态代理的功能增强方式。

1.3 Spring的优点

  • 方便解耦,简化开发
    • Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
  • AOP编程的支持
    • Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  • 声明式事务的支持
    • 只需要通过配置就可以完成对事务的管理,而无需手动编程
  • 方便程序的测试
    • Spring对Junit4支持,可以通过注解方便的测试Spring程序
  • 方便集成各种优秀框架
    • Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持
  • 降低JavaEE API的使用难度
    • Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

关于框架的特性,我们也会俗称Spring为开发架构的粘合剂。

二. Spring框架的快速入门

2.1 搭建环境

  1. 下载开发包,导jar包
    
    下载网址:http://repo.spring.io/libs-release-local/org/springframework/spring/

    开发包目录结构:
        docs : api文档和开发规范
        libs : 开发需要的jar包(源码)
        schema : 开发需要的约束schema
    -----------------------------------------------------------------------------

    1. 新建web项目
    2. Spring项目的核心容器最基本的jar包(4个):
        1. Beans  2. Core  3. Context  4.Expression Language
    3. Spring框架需要的日志包(2个,依赖库中找)
        1. apache commons-logging(JCL)日志框架  
        2. log4j的日志实现
        3. log4j的配置文件 log4j.properties
    
    

2.2 业务代码

模拟用户保存。

img01.png

    传统写法 :

    UserServiceImpl : 
        // 模拟用户注册
        public void save() {
            // 传统方式
            System.out.println("业务层........UserServiceImpl用户注册...");
            UserDAO dao = new UserDAOImpl();
            userDAO.save();
        }


    UserDAO : 
        //模拟用户注册
        public void save() {
            System.out.println("持久层.......UserDAOImpl用户注册...");
        }

    web层(这里是测试test):
        @Test
        public void test() {
            UserService service = new UserServiceImpl();
            service.save();
        }

    传统的方式代码过于耦合,上层代码过于依赖下层代码,如果业务有改动,要改变DAO的实现类时,需要改动代码:
    UserDAO userDAO = new UserDaoImpl();因此需要采取方式进行解耦合。

    解决方案:采用IoC(Inverse of Control)控制反转的思想进行解耦合.

    简单的说就是引入工厂(第三者),将原来在程序中手动创建管理的依赖的UserDAO对象,交给工厂来创建管理。
    在Spring框架中,这个工厂就是Spring中的工厂,因此,也可以说,将创建管理UserDAO对象的控制权被反转给了Spring框架了。

    -----------------------------------------------------------------------------

    概念:IoC中文翻译为控制反转,指以前程序自己创建对象,现在将创建对象的控制权交给了第三方(Spring)了。

    IoC底层实现:工厂(设计模式)+反射(机制) + 配置文件(xml)。

    IoC是一种思想,控制反转的思想、解耦合的思想。
    Spring的IoC是该思想的一种实现。因此Spring容器也通常称之为IoC容器。

img02.png

2.3 IoC控制反转的实现

传统是自己创建对象,现在将创建对象交给Spring容器,我们获取就行了.

这种方式,即使更换实现类,也只需要修改配置文件中的实现类的路径。

2.3.1 Spring的核心配置文件编写applicationContext.xml

1. 习惯上: 在src建立applicationContext.xml (位置:src目录或者 WEB-INF目录)

2. 引入xml的头部信息bean schema约束,可以参考规范文档中的的xsd-config.html
    <?xml version="1.0" encoding="UTF-8"?>
    
    <!-- 导入Spring的DTD约束 -->
    <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">
            
        <bean id="userDAO" class="com.itdream.spring.dao.UserDAOImpl"/>
        <bean id="userService" class="com.itdream.spring.service.UserServiceImpl">
            <property name="userDAO" ref="userDAO"/>
        </bean>        
    </beans>

3.  配置实现类的映射bean
    <bean id="userDAO" class="com.itdream.spring.dao.UserDAOImpl"/>

2.3.2 通过Spring的工厂获取Bean完成相关操作

  1. 读取配置文件,获取Spring的Bean工厂

  2. 通过Spring的Bean工厂获取对象

     // Spring解耦合,使用配置文件:创建工厂+反射创建UserDAO对象
     // 加载配置文件,获取工厂对象
     ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
     // 实例化对象
     UserDAO dao = (UserDAO) applicationContext.getBean("userDAO");
     userDAO.save();
    

2.4 DI依赖注入的实现

DI:Dependency Injection 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件(简单的说,可以将另外一个bean对象动态的注入到另外一个bean中。)

耦合代码变成依赖注入代码的方法:

img03.png

即:Spring创建了Service、DAO对象,在配置中将DAO传入Servcie,那么Service对象就包含了DAO对象的引用。

在Service对象创建调用时,也会产生一个DAO对象,并通过Service内提供的setter方法将该对象的引用注入进去。

applicationContext.xml核心配置文件:
    <!-- 配置userDAO的创建映射,Spring框架通过这个映射来new对象 -->
    <bean id="userDAO" class="com.itdream.spring.dao.UserDAOImpl"/>
    
    <!-- 配置userService的创建映射,Spring通过该映射创建Service对象 -->
    <bean id="userService" class="com.itdream.spring.service.UserServiceImpl">
        <!-- property:属性注入
            name : setter方法的名字,例如setUserDAO-userDAO。
            //注入时,Spring会自动调用setter方法,将创建出来的对象放入到该方法中完成注入
            ref : 创建该对象的引用,写入被Spring管理的bean的name属性
         -->
        <property name="userDAO" ref="userDAO"/>
    </bean> 


Service层:
    声明注入的对象,提供setter方法
        private UserDAO userDAO;
        
        //提供setter方法Spring方法进行动态注入userDAO
        public void setUserDAO(UserDAO userDAO) {
            this.userDAO = userDAO;
        }
        
        @Override
        // 模拟用户注册
        public void save() {
            //Spring框架创建了userDAO对象并注入进来,因此不会是空
            userDAO.save();
        }

web层:
    //加载配置,获取Spring工厂(容器)
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
    //获取bean对象
    UserService userService = (UserService) applicationContext.getBean("userService");
    //调用业务逻辑
    userService.save();

img04.png

小结:

IoC:是一个大的思想,将某件事情(对象创建权利等)的控制前交给第三方管理。
DI:还是IoC的思想,将对象依赖注入权利交给第三方管理。

2.5 Spring的工厂

ApplicationContext用来加载Spring框架的配置文件,来构建Spring对象的工厂对象,它被称为Spring框架的上下文,
也被称为Spring的容器。

ApplicationContext是BeanFactory(Bean工厂,Bean就是一个java对象)的一个子接口。

为什么不直接使用顶层接口对象来操作呢?
因为ApplicationContext是对BeanFactory的扩展,它的功能更强。
    * 国际化处理
    * 事件传递
    * Bean的自动装配
    * 不同应用层的Context的实现

2.5.1 获取Spring工厂的两种方式

src:开发的时候,工程里的一个目录,存放的文件,会在编译发布后,放入classes下

img05.png
  • 如果applicationContext.xml 在 src下, ClassPathXmlApplication读取
  • 如果applicationContext.xml 在WEB-INF下,FileSystemXmlApplicationContext读取

三. IoC容器装配Bean_基于XML配置方式

3.1 实例化Bean的四种方式(了解)

  • 无参构造/带参构造方式
  • 静态工厂方式
  • 实例工厂方式
  • FactoryBean方式

    1. 无参构造/带参构造方式:
    public class Bean1 {
        //无参构造
        public Bean1() {
            System.out.println("Bean1被创建了............无参构造");
        }
    }

    public class Bean2 {
    
        private Integer id;
        private String name;
        
        //提供带参构造
        public Bean2(Integer id, String name) {
            System.out.println("Bean2被创建了..........带参构造");
            this.id = id;
            this.name = name;
        }
    }


    配置文件applicationContext.xml:
        <!-- 无参构造实例化Bean -->
        <bean id="bean1" class="com.itdream.spring.newBean.Bean1"/>
        
        <!-- 带参构造实例化Bean -->
        <bean id="bean2" class="com.itdream.spring.newBean.Bean2">
            <constructor-arg name="id" value="1"/>
            <constructor-arg name="name" value="唐嫣"/>
        </bean>
    
img06.png

2. 静态工厂方式 : 通过静态工厂的静态方法创建bean对象

要被反转控制的Bean类:
    public class Bean3 {
        public Bean3() {
                System.out.println("Bean3被创建了.....静态工厂方式");
            }
        }
静态工厂类提供静态方法:
    public class StaticBean3Factory {
    
        public static Bean3 getBean3() {
            //在实例化时,可以进行其它操作,例如逻辑判断等
            return new Bean3();
        }
    }   

配置文件:
    <!-- 静态工厂方式实例化Bean -->
    <bean id="bean3" class="com.itdream.spring.newBean.StaticBean3Factory" factory-method="getBean3"/>

3. 实例化工厂方式:

要被反转控制的Bean类:
    public class Bean4 {
        public Bean4() {
            System.out.println("Bean4被创建了.......实例化工厂方式");
        }
    }

实例化工厂类提供创建Bean的方法:
    public class Bean4Factory {
        // 实例化工厂方式创建Bean对象
        public Bean4 initBean() {
            // 可以在new Bean4之前进行很多的逻辑判断
            // 例如判断new哪一个对象
            return new Bean4();
        }
    }

配置文件:
    <!-- 实例化工厂方式实例化Bean -->
    <!-- 先实例化工厂,再通过实例化的工厂调用方法创建对象 -->
    <bean id="bean4Factory" class="com.itdream.spring.newBean.Bean4Factory"/>
    <bean id="bean4" factory-bean="bean4Factory" factory-method="initBean"/>

4. FactoryBean方式:
    实现接口,实现getObject方法,返回要创建的Bean类.Spring检查到实现了FactoryBean接口时,会在实例化
    FactoryBean时自动调用getObject方法获取Bean对象。

    public class FactoryBean5 implements FactoryBean<Bean5> {
    
        @Override
        public Bean5 getObject() throws Exception {
            return new Bean5();
        }


    <!-- FactoryBean方式实例化Bean -->
    <bean id="beanFactory5" class="com.itdream.spring.newBean.FactoryBean5"/>

小结:
四种方式:
第一种最常用,第二、三、一些框架初始化的时候用的多、第四种spring底层用的多。


    <!-- 实例化Bean的四种方式 -->
    <!-- 无参构造实例化Bean -->
    <bean id="bean1" class="com.itdream.spring.newBean.Bean1"/>
    
    <!-- 带参构造实例化Bean -->
    <bean id="bean2" class="com.itdream.spring.newBean.Bean2">
        <constructor-arg name="id" value="1"/>
        <constructor-arg name="name" value="唐嫣"/>
    </bean>
    
    <!-- 静态工厂方式实例化Bean -->
    <bean id="bean3" class="com.itdream.spring.newBean.StaticBean3Factory" factory-method="getBean3"/>
    <!-- 实例化工厂方式实例化Bean -->
    <!-- 先实例化工厂,再通过实例化的工厂调用方法创建对象 -->
    <bean id="bean4Factory" class="com.itdream.spring.newBean.Bean4Factory"/>
    <bean id="bean4" factory-bean="bean4Factory" factory-method="initBean"/>
    
    <!-- FactoryBean方式实例化Bean -->
    <bean id="beanFactory5" class="com.itdream.spring.newBean.FactoryBean5"/>

    ---------------------------------------------------------------------------

    BeanFactory和FactoryBean的区别?
 
    BeanFactory(ApplicationContext):
        是一个工厂(其实是构建了一个spring上下文的环境,容器),用来管理和获取很多Bean对象.
    FactoryBean:
        是一个Bean生成工具,是用来获取一种类型对象的Bean,它是构造Bean实例的一种方式。

3.2 Bean的作用域

img07.png

项目开发中通常会使用:singleton 单例、 prototype多例 。

Singleton: 在一个spring容器中,对象只有一个实例。(默认值)

Prototype: 在一个spring容器中,存在多个实例,每次getBean 返回一个新的实例。

单例是默认值,如果需要单例对象,则不需要配置scope。
img08.png

3.3 在xml配置Bean的初始化和销毁方法(了解)

  • 说明:Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring可以在创建和拆卸bean的时候调用bean的两个生命周期方法
  • init-method -- 当bean被载入到容器的时候调用init-method属性指定的方法
  • destroy-method -- 当bean从容器中删除的时候调用destroy-method属性指定的方法

    想查看destroy-method的效果,有如下条件
        1. 单例(singleton)的bean才可以手动销毁。
        2. web容器中会自动调用,但是main函数或测试用例需要手动调用(需要使用ClassPathXmlApplicationContext的close()方法)


    public class LifeCycleBean {
        public LifeCycleBean() {
            System.out.println("实例化................");
        }
        
        public void init() {
            System.out.println("初始化...............");
        }
        
        public void destroy() {
            System.out.println("销毁................");
        }
    }

    配置文件:
    <!-- 生命周期测试 -->
    <bean id="lifeCycle" class="com.itdream.spring.lifecycle.LifeCycleBean" init-method="init" destroy-method="destroy"/>
    

测试:

img09.png

3.4 Bean的属性依赖注入

3.4.1 属性依赖注入的三种方式

  • 构造器参数注入
  • setter方法属性注入
  • 接口注入(了解)

Spring 框架规范中通过配置文件配置的方式,只支持构造器参数注入和setter方法属性注入,不支持接口注入 !

3.4.2 构造器参数注入constructor-arg

当Spring初始化Car时,如果发现有constructor-arg标签,会自动调用带参构造,而不会使用无参构造。

constructor-arg的属性:

  • name : 根据属性名称定位属性
  • index : 根据索引定位属性
  • type : 根据属性的类型定位属性
  • ================================
  • value : 简单值,数字,字符串,其他对象等等
  • ref : 复杂的对象(就是指bean),值:bean的引用名字

    Bean类:

    public class Car {
        private Integer id;
        private String name;
        private Double price;
    
        // 必须提供带参构造,用于属性注入
        public Car(Integer id, String name, Double price) {
            super();
            this.id = id;
            this.name = name;
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Car [id=" + id + ", name=" + name + ", price=" + price + "]";
        }
    }


    配置文件applicationContext.xml:

    <!-- 带参构造属性注入 -->
    <bean id="car" class="com.itdream.spring.di.Car">
        <constructor-arg index="0" value="1"/>
        <constructor-arg name="name" value="宝马"/>
        <constructor-arg type="java.lang.Double" value="999999D"/>
    </bean> 

    测试:
    @Test
    public void test() {
        // 加载配置文件,获取Spring工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        //获取Bean对象
        Car car = (Car) applicationContext.getBean("car");
        System.out.println(car);
    }

    结果:
        Car [id=1, name=宝马, price=999999.0]

补充:

1. 定位属性的标签,可以混用
    即:<constructor-arg index="0" name="name" type="java.lang.Double"/>

2. 自标签的属性赋值问题,可以使用子标签的value,效果和value属性一样
    如:
    <constructor-arg name="name">
        <value>宝马</value>
    </constructor-arg>

3.4.3.setter方法属性注入 property【推荐】

使用的默认的构造器(new Bean()),但必须提供属性的setter方法。

Spring创建出Bean对象,再通过setter方法属性注入值。

两步:在类中加入setter方法,在配置文件中使用property

    
    Bean类:

    public class Person {
    
        private Integer pid;
        private String name;
        private Car car;
        
        //必须提供setter方法,用于属性注入
        public void setPid(Integer pid) {
            this.pid = pid;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
        @Override
        public String toString() {
            return "Person [pid=" + pid + ", name=" + name + ", car=" + car + "]";
        }
    }

    配置文件applicationContext.xml:

        <!-- 带参构造属性注入 -->
        <bean id="car" class="com.itdream.spring.di.Car">
            <constructor-arg index="0" value="1" />
            <constructor-arg name="name" value="宝马" />
            <constructor-arg type="java.lang.Double" value="999999" />
        </bean>

        <!-- setter方法属性注入 -->
        <bean id="person" class="com.itdream.spring.di.Person ">
            <property name="pid" value="1" />
            <property name="name" value="jack" />
            <property name="car" ref="car"/>
        </bean> 

    测试:

        @Test
        public void test() {
            // 加载配置文件,获取Spring工厂
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            
            //获取Bean对象
            //将创建对象与属性注入的权利交给Spring,我们直接从容器拿到这个对象就可以了(已经包含了属性的值)
            Person person = (Person) applicationContext.getBean("person");
            System.out.println(person);
        }

    结果:
        Person [pid=1, name=jack, car=Car [id=1, name=宝马, price=999999.0]]

setter方法属性注入的属性:

property : 用于setter方式进行属性注入的标签
name : 与Bean类中的setter方法对应.例如setCar --- name就是car.
value : 简单值.
ref : 复杂值。要注入的Bean对象的id/name名字

3.4.4.p名称空间的使用(了解)

什么是名称空间? 
作用:Schema区分同名元素。(有点类似于java的包)

xmlns="http://www.springframework.org/schema/beans"
Xmlns没有前缀是默认的名称空间.

p名称空间的作用是为了简化setter方法属性依赖注入配置的,它不是真正的名称空间。

它的使用方法:
    p:<属性名>="" 引入常量值
    p:<属性名>-ref =""引入其他Bean对象


具体使用步骤:
    1. 引入p名称空间
    <beans xmlns="http://www.springframework.org/schema/beans"

        //在这里引入p名称空间(默认名称空间后,在xmlns后添加:p , 将最后的beans改成p。)
       xmlns:p="http://www.springframework.org/schema/p"

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

    2. 将<property> 子元素 简化为 元素的属性 (以上面的person为例)
    <!-- P名称空间简化setter方法属性注入 -->
    <bean id="person" class="com.itdream.spring.di.Person" p:pid="2" p:name="coco" p:car-ref="car"/>

    结果:
    Person [pid=2, name=coco, car=Car [id=1, name=宝马, price=999999.0]]

    配置时不需要<property > 子元素,简化了配置 .

3.4.5 spEL表达式的使用 –会使用

spEL(Spring Expression Language)是一种表达式语言,它是spring3.x版本的新特性。

作用:支持在运行时操作和查询对象,其语法类似统一的EL语言,但是SpEL提供了额外的功能,功能更强大。

img11.png

语法: #{…} , 引用另一个Bean 、属性、 方法

  • #{bean_id}引用Bean(具体对象)
  • #{bean_id.属性}引用Bean的属性
  • #{bean_id.方法(参数)}引用Bean的方法

    例1:

    //修改了p:pid的值为#{2*3},修改p:name为#{car.name},car是创建car对象的id。
        car.name相当于调用了它的getName()方法,因此Car的Bean类中必须提供getName方法。
    <bean id="person" class="com.itdream.spring.di.Person" p:pid="#{2*3}" p:name="#{car.name}" p:car-ref="car"/>

    测试结果:
    Person [pid=6, name=宝马, car=Car [id=1, name=宝马, price=999999.0]]    


    例2:
    //修改了p:pid的值为#{car.id},修改p:name为#{car.name},car是创建car对象的id。
        car.id相当于调用了它的getId()方法,因此Car的Bean类中必须提供getId方法。
    <bean id="person" class="com.itdream.spring.di.Person" p:pid="#{car.id}" p:name="#{'bmw'.toUpperCase()}" p:car-ref="car"/>

    测试结果:
    Person [pid=1, name=BMW, car=Car [id=1, name=宝马, price=999999.0]]

3.4.6.集合类型属性注入 (了解-使用时查看即可)

作用:主要用于框架整合配置。

Spring为集合提供了对应的标签:
    <list> 注入 list元素
    <set> 注入 set元素
    <map> 注入 map元素
    <props> 注入 properties 元素 (hashtable类的子类,是特殊的map,key和value都是String )

    
    Bean类:提供四种集合,List,Map,Set,Properties,使用setter方式进行属性注入:

    public class CollectionBean {
    
        private List<Integer> list;
        private Set<String> set;
        private Map<String, String> map;
        private Properties properties;
    
        // 提供setter方式,供Spring框架属性注入
        public void setList(List<Integer> list) {
            this.list = list;
        }
    
        public void setSet(Set<String> set) {
            this.set = set;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    
        public void setProperties(Properties properties) {
            this.properties = properties;
        }
    
        @Override
        public String toString() {
            return "CollectionBean [list=" + list + ", set=" + set + ", map=" + map + ", properties=" + properties + "]";
        }
    }
    ======================================================================================

    applicationContext.xml :

        value注入简单类型。   ref注入复杂类型。

        <bean id="collectionBean" class="com.itdream.spring.collection.CollectionBean">
        <property name="list">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
                <value>4</value>
             </list>
        </property>
        
        <property name="set">
            <set>
                <value>aa</value>
                <value>bb</value>
                <value>cc</value>
                <value>dd</value>
            </set>
        </property>
        
        <property name="map">
            <map>
                <entry key="罗贯中" value="三国演义"/>
                <entry key="施耐庵" value="水浒传"/>
                <entry key="曹雪芹" value="红楼梦"/>
                <entry key="吴承恩" value="西游记"/>
            </map>
        </property>
        
        <property name="properties">
            <props>
                <prop key="霍建华">林心如</prop>
                <prop key="吴奇隆">李诗诗</prop>
            </props>
        </property>
    </bean>

    测试:
        // 加载配置文件,获取Spring工厂
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        //获取Bean对象
        CollectionBean collectionBean = (CollectionBean) applicationContext.getBean("collectionBean");
        System.out.println(collectionBean);

    结果:
    CollectionBean [list=[1, 2, 3, 4], set=[aa, bb, cc, dd], map={罗贯中=三国演义, 施耐庵=水浒传, 曹雪芹=红楼梦, 吴承恩=西游记}, properties={霍建华=林心如, 吴奇隆=李诗诗}]

3.5.配置文件分开管理(了解)

在开发中,所有的bean不可能只写在一个配置文件中,如果在src的目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加载这两个配置文件的方式有两种:

  • 主配置文件中包含其他的配置文件:【推荐】

      在applicationContext.xml中:
      <import resource="applicationContext2.xml"/>
    
  • 工厂创建的时候直接加载多个配置文件:

    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml","applicationContext2.xml");
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,651评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,803评论 6 342
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan阅读 4,151评论 2 7
  • 什么是Spring Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Jav...
    jemmm阅读 16,461评论 1 133
  • 心脏公司的野心不言而喻,如果他们停摆,那么大脑也会失去给养停止运作。细枝末节爬虫们的盛会一定预示着什么,不只是场没...
    贱金属阅读 316评论 0 0