天天看点

Spring入门案例

Spring入门案例代码

1.创建Maven的java项目

Spring入门案例

2.pom.xml添加Spring的依赖jar包

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>spring_01_quickstart</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>
           

3.创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类

package com.itheima.dao;

public interface BookDao {
    public void save();

}

package com.itheima.dao.impl;

import com.itheima.dao.BookDao;

public class BookDaoImpl implements BookDao {
    public void save() {
      System.out.println("book dao save ...");
    }
}

package com.itheima.service;

public interface BookService {
    public void save();
}

package com.itheima.service.impl;

import com.itheima.dao.BookDao;
import com.itheima.dao.impl.BookDaoImpl;
import com.itheima.service.BookService;

public class BookServiceImpl implements BookService {
        //5.删除业务层中使用new的方式创建的dao对象
        private BookDao bookDao;
        public void save() {
            System.out.println("book service save ...");
            bookDao.save();
        }
            //6.提供对应的set方法
        public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}


           

4.resources下添加spring配置文件,并完成bean的配置

applicationContext.xmll

<?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">
    <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

    <!--2.配置bean-->
    <!--bean标签标示配置bean
    id属性标示给bean起名字
    class属性表示给bean定义类型-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <!--7.配置server与dao的关系-->
        <!--property标签表示配置当前bean的属性
        name属性表示配置哪一个具体的属性
        ref属性表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>

</beans>           

注意:配置中的两个bookDao的含义是不一样的

name="bookDao"中bookDao的作用是让Spring的IOC容器在获取到名称后,将首字母大写,前 面加set找对应的setBookDao()方法进行对象注入

ref="bookDao"中bookDao的作用是让Spring能在IOC容器中找到id为bookDao的Bean对象给

bookService进行注入

综上所述,对应关系如下:

Spring入门案例

5.从容器中获取对象进行方法调用

package com.itheima;

import com.itheima.dao.BookDao;
import com.itheima.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    public static void main(String[] args) {
     //获取IOC容器
          ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
          BookService bookService = (BookService) ctx.getBean("bookService");
          bookService.save();
     }
}           

以上完成了入门案例代码。

bean基础配置

bean基础配置(id与class)

Spring入门案例

bean的name属性

name为bean指定别名,别名可以有多个,使用逗号,空格、分号隔开。

Spring入门案例
Spring入门案例

根据名称容器中获取bean对象

public class AppForName {

public static void main(String[] args) {

ApplicationContext ctx = new

ClassPathXmlApplicationContext("applicationContext.xml");

//此处根据bean标签的id属性和name属性的任意一个值来获取bean对象

BookService bookService = (BookService) ctx.getBean("service4");

bookService.save();

}

}

bean作用范围scope配置

Spring入门案例
Spring入门案例

bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象

bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高

bean在容器中是单例的,会不会产生线程安全问题?

如果对象是有状态对象,即该对象有成员变量可以用来存储数据的, 因为所有请求线程共用一个bean对象,所以会存在线程安全问题。

如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的, 因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。

封装实例的域对象,因为会引发线程安全问题,所以不适合。

哪些bean对象适合交给容器进行管理?

表现层对象 业务层对象 数据层对象 工具对象

bean实例化方法

构造方法实例化

<!--方式一:构造方法实例化bean-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>           

Spring底层使用的是类的无参构造方法。关于Spring的构造方法实例化就已经学习完了,因为每一个类默认都会提供一个无参构造函 数,所以其实真正在使用这种方式的时候,我们什么也不需要做。这也是我们以后比较常用的一种方式。

静态工厂实例化

<!--方式二:使用静态工厂实例化bean-->
    <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
           
Spring入门案例

看到这,可能有人会问了,你这种方式在工厂类中不也是直接new对象的,和我自己直接new没什么太 大的区别,而且静态工厂的方式反而更复杂,这种方式的意义是什么?

主要的原因是:

在工厂的静态方法中,我们除了new对象还可以做其他的一些业务操作,这些操作必不可少,如:

public class OrderDaoFactory {

public static OrderDao getOrderDao(){

System.out.println("factory setup....");//模拟必要的业务操作

return new OrderDaoImpl();

}

}

之前new对象的方式就无法添加其他的业务内容。

实例工厂与FactoryBean

接下来继续来研究Spring的第三种bean的创建方式实例工厂实例化:

环境准备

(1)准备一个UserDao和UserDaoImpl类

public interface UserDao {

public void save();

}

public class UserDaoImpl implements UserDao {

public void save() {

System.out.println("user dao save ...");

}

}

(2)创建一个工厂类OrderDaoFactory并提供一个普通方法,注意此处和静态工厂的工厂类不一样的 地方是方法不是静态方法

public class UserDaoFactory {

public UserDao getUserDao(){

return new UserDaoImpl();

}

}

(3)编写AppForInstanceUser运行类,在类中通过工厂获取对象

// //创建实例工厂对象

UserDaoFactory userDaoFactory = new UserDaoFactory();

// //通过实例工厂对象创建对象

UserDao userDao = userDaoFactory.getUserDao();

userDao.save();

实例工厂实例化

具体实现步骤为:

(1)在spring的配置文件中添加以下内容:

<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>

<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

实例化工厂运行的顺序是:

创建实例化工厂对象,对应的是第一行配置

调用对象中的方法来创建bean,对应的是第二行配置

factory-bean:工厂的实例对象

factory-method:工厂对象中的具体创建对象的方法名,对应关系如下:

Spring入门案例

factory-mehod:具体工厂类中创建对象的方法名

(2)在AppForInstanceUser运行类,使用从IOC容器中获取bean的方法进行运行测试

public class AppForInstanceUser {
    public static void main(String[] args) {
        ApplicationContext ctx = new 
            ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) ctx.getBean("userDao");
        userDao.save();
   }
}           

实例工厂实例化的方式就已经介绍完了,配置的过程还是比较复杂,所以Spring为了简化这种配置方 式就提供了一种叫FactoryBean的方式来简化开发。

FactoryBean的使用

具体的使用步骤为:

(1)创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //代替原始实例工厂中创建对象的方法

            public UserDao getObject() throws Exception {
        return new UserDaoImpl();
   }
    //返回所创建类的Class对象

            public Class<?> getObjectType() {
        return UserDao.class;
   }
}           

(2)在Spring的配置文件中进行配置

<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>           

(3)AppForInstanceUser运行类不用做任何修改,直接运行

查看源码会发现,FactoryBean接口其实会有三个方法,分别是:

T getObject() throws Exception;


Class<?> getObjectType();


default boolean isSingleton() {
    return true;
}           

方法一:getObject(),被重写后,在方法中进行对象的创建并返回

方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象

方法三:没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默 认true.

那如果想改成单例具体如何实现?

只需要将isSingleton()方法进行重写,修改返回为false,即可

//FactoryBean创建对象

public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //代替原始实例工厂中创建对象的方法

            public UserDao getObject() throws Exception {
        return new UserDaoImpl();
   }

    public Class<?> getObjectType() {

        return UserDao.class;
   }
 
    public boolean isSingleton() {
        return false;
   }
}           

但是一般情况下我们都会采用单例,也就是采用默认即可。 所以isSingleton()方法一般不需要进行重写。

bean的生命周期

首先理解下什么是生命周期?

从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。

bean生命周期是什么? bean对象从创建到销毁的整体过程。

bean生命周期控制是什么?在bean创建后到销毁前做一些事情。

生命周期设置

添加生命周期的控制方法,具体的控制有两个阶段:

bean创建之后,想要添加内容,比如用来初始化需要用到资源

bean销毁之前,想要添加内容,比如用来释放用到的资源

步骤1:添加初始化和销毁方法

针对这两个阶段,我们在BooDaoImpl类中分别添加两个方法,方法名任意

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
   }
    //表示bean初始化对应的操作

            public void init(){
        System.out.println("init...");
   }
    //表示bean销毁前对应的操作

            public void destory(){
        System.out.println("destory...");
   }
}

           

步骤2:配置生命周期

在配置文件添加配置,如下:

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init"

        destroy-method="destory"/>
           

步骤3:运行程序

Spring入门案例

从结果中可以看出,init方法执行了,但是destroy方法却未执行,这是为什么呢?

Spring的IOC容器是运行在JVM中 运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方 法执行main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了 所以没有调用对应的destroy方法.

知道了出现问题的原因,具体该如何解决呢?

close关闭容器

  • ApplicationContext中没有close方法
  • 需要将ApplicationContext更换成ClassPathXmlApplicationContext
ClassPathXmlApplicationContext ctx = new 
   ClassPathXmlApplicationContext("applicationContext.xml");
           
  • 调用ctx的close()方法
ctx.close();           
  • 运行程序,就能执行destroy方法的内容

注册钩子关闭容器

  • 在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
  • 调用ctx的registerShutdownHook()方法
ctx.registerShutdownHook();           

注意:registerShutdownHook在ApplicationContext中也没有

两种方式介绍完后,close和registerShutdownHook选哪个?

相同点:这两种都能用来关闭容器

不同点:close()是在调用的时候关闭,registerShutdownHook()是在JVM退出前调用关闭。 分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多 也比较乱。

Spring提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置init-method和

destroy-method

接下来在BookServiceImpl完成这两个接口的使用:

修改BookServiceImpl类,添加两个接口InitializingBean, DisposableBean并实现接口中的 两个方法afterPropertiesSet和destroy

public class BookServiceImpl implements BookService, InitializingBean,

        DisposableBean {
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
   }
    public void save() {
        System.out.println("book service save ...");
        bookDao.save(); 
   }
    public void destroy() throws Exception {
        System.out.println("service destroy");
   }
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
   }
}           

那第二种方式的实现,我们也介绍完了。

小细节

  • 对于InitializingBean接口中的afterPropertiesSet方法,翻译过来为属性设置之后。
  • 对于BookServiceImpl来说,bookDao是它的一个属性
  • setBookDao方法是Spring的IOC容器为其注入属性的方法
  • afterPropertiesSet和setBookDao是setBookDao方法先执行

DI依赖注入

setter注入

  1. 注入引用类型对象
  • 在bean中定义引用类型属性,并提供可访问的set方法
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
   }
}           

配置中使用property标签ref属性注入引用类型对象

<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

<property name="bookDao" ref="bookDao"/>
</bean>



<bean id="bookDao" class="com.itheima.dao.imipl.BookDaoImpl"/>           

2.注入简单数据类型

步骤1:声明属性并提供setter方法

public class BookDaoImpl implements BookDao {
 
    private String databaseName;
    private int connectionNum;
 
    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
   }
 
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
   }
 
    public void save() {
        System.out.println("book dao save 
..."+databaseName+","+connectionNum);
   }
}
           

步骤2:配置文件中进行注入配置

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


           <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

               <property name="databaseName" value="mysql"/>

            <property name="connectionNum" value="10"/>

           </bean>

           <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

           <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

               <property name="bookDao" ref="bookDao"/>

               <property name="userDao" ref="userDao"/>

           </bean>

</beans>
           

value:后面跟的是简单数据类型,对于参数类型,Spring在注入的时候会自动转换。

对于setter注入方式的基本使用就已经介绍完了, 对于

引用数据类型使用的是<property name="" ref=""/>

对于简单数据类型使用的是<property name="" value=""/>

构造器注入

  1. 构造器注入引用数据类型

步骤1:提供构造方法

public class BookServiceImpl implements BookService{
    private BookDao bookDao;
 
    public BookServiceImpl(BookDao bookDao) {
        this.bookDao = bookDao;
   }
 
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
   }
}
           

步骤2:配置文件中进行配置构造方式注入

在applicationContext.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">


           <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

           <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

               <constructor-arg name="bookDao" ref="bookDao"/>

           </bean>
</beans>           

说明:

标签中

  • name属性对应的值为构造函数中方法形参的参数名,必须要保持一致。
  • ref属性指向的是spring的IOC容器中其他bean对象。

构造器注入多个引用数据类型

步骤1:提供多个属性的构造函数

步骤2:配置文件中配置多参数注入

构造器注入多个简单数据类型

步骤1:添加多个简单属性并提供构造方法

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;
 
    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
   }
 
    public void save() {
        System.out.println("book dao save 
..."+databaseName+","+connectionNum);
   }
}           

步骤2:配置完成多个属性构造器注入

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

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

               <constructor-arg name="databaseName" value="mysql"/>

               <constructor-arg name="connectionNum" value="666"/>

           </bean>

           <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

           <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

               <constructor-arg name="bookDao" ref="bookDao"/>

               <constructor-arg name="userDao" ref="userDao"/>

           </bean>
</beans>           
  • 当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变 这两块存在紧耦合,具体该如何解决?

方式一:删除name属性,添加type属性,按照类型注入

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

           <constructor-arg type="int" value="10"/>

           <constructor-arg type="java.lang.String" value="mysql"/>
</bean>           
  • 这种方式可以解决构造函数形参名发生变化带来的耦合问题
  • 但是如果构造方法参数中有类型相同的参数,这种方式就不太好实现了

方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

           <constructor-arg index="1" value="100"/>

           <constructor-arg index="0" value="mysql"/>
</bean>           
  • 这种方式可以解决参数类型重复问题
  • 但是如果构造方法参数顺序发生变化后,这种方式又带来了耦合问题

介绍完两种参数的注入方式,具体我们该如何选择呢?

  1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现 强制依赖指对象在创建的过程中必须要注入指定的参数
  2. 可选依赖使用setter注入进行,灵活性强 可选依赖指对象在创建过程中注入的参数可有可无
  3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相 对严谨
  4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选 依赖的注入
  5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注 入
  6. 自己开发的模块推荐使用setter注入

依赖自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配

自动装配方式有哪些?

  • 按类型(常用)
  • 按名称
  • 按构造方法
  • 不启用自动装配

自动装配只需要修改applicationContext.xml配置文件即可:

(1)将标签删除

(2)在标签中添加autowire属性

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


           <bean class="com.itheima.dao.impl.BookDaoImpl"/>

           <!--autowire属性:开启自动装配,通常使用按类型装配-->

           <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"

        autowire="byType"/>



</beans>
           

注意事项:

需要注入属性的类中对应属性的setter方法不能省略 被注入的对象必须要被Spring的IOC容器管理 按照类型在Spring的IOC容器中如果找到多个对象,会报NoUniqueBeanDefinitionException

一个类型在IOC中有多个对象,还想要注入成功,这个时候就需要按照名称注入,配置方式为:

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


           <bean class="com.itheima.dao.impl.BookDaoImpl"/>

           <!--autowire属性:开启自动装配,通常使用按类型装配-->

           <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"

        autowire="byName"/>



</beans>
           

最后对于依赖注入,需要注意一些其他的配置特征:

1. 自动装配用于引用类型依赖注入,不能对简单类型进行操作

2. 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用

3. 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推 荐使用

4. 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效

集合注入

前面我们已经能完成引入数据类型和简单数据类型的注入,但是还有一种数据类型集合,集合中既可 以装简单数据类型也可以装引用数据类型,对于集合,在Spring中该如何注入呢?

先来回顾下,常见的集合类型有哪些?

  • 数组
  • List
  • Set
  • Map
  • Properties

举例——

(1)项目中添加添加BookDao、BookDaoImpl类

public interface BookDao {
           public void save();
        }


        public class BookDaoImpl implements BookDao {
           

        public class BookDaoImpl implements BookDao {

           private int[] array;

           private List<String> list;

   private Set<String> set;

       private Map<String,String> map;

       private Properties properties;

        public void save() {

    System.out.println("book dao save ...");

           System.out.println("遍历数组:" + Arrays.toString(array));

           System.out.println("遍历List" + list);

           System.out.println("遍历Set" + set);

           System.out.println("遍历Map" + map);

           System.out.println("遍历Properties" + properties);
      }
    //setter....方法省略,自己使用工具生成

    }           

(2)resources下提供spring的配置文件,applicationContext.xml

下面的所以配置方式,都是在bookDao的bean标签中使用进行注入

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


           <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

       
   </bean>
        </beans>           

注入数组类型数据

<property name="array">

   <array>

           <value>100</value>

           <value>200</value>

           <value>300</value>

       </array>
</property>
           

注入List类型数据

<property name="list">

   <list>

           <value>itcast</value>

           <value>itheima</value>

           <value>boxuegu</value>

           <value>chuanzhihui</value>

       </list>
</property>           

注入Set类型数据

<property name="set">

   <set>

           <value>itcast</value>

           <value>itheima</value>

           <value>boxuegu</value>

           <value>boxuegu</value>

       </set>
</property>           

注入Map类型数据

<property name="map">

   <map>

           <entry key="country" value="china"/>

           <entry key="province" value="henan"/>

           <entry key="city" value="kaifeng"/>

       </map>
</property>           

注入Properties类型数据

<property name="properties">

   <props>

           <prop key="country">china</prop>

           <prop key="province">henan</prop>

           <prop key="city">kaifeng</prop>

       </props>
</property>           

说明:

  • property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写
<array>、<list>、<set>、<map>、<props>标签           
  • List的底层也是通过数组实现的,所以和标签是可以混用
  • 集合中要添加引用类型,只需要把标签改成标签,这种方式用的比较少