Spring介绍

Spring Framework是Spring生态圈中最基础的项目,是其他项目的根基。

从spring的版本更迭中可以看出,spring的架构在不断的模块化,解耦程度越来越高,尽量实现低耦合高内聚。

01-2-Spring系统架构.pptx -20230102-706

03-04-Spring系统架构.pptx -20230102-491

目前版本为止spring的架构图如下:

springFramework架构-5
  • Data Access:数据访问
  • Data Integration:数据集成
  • Web:Web开发
  • AOP:面向切面编程
  • Aspects:AOP思想实现
  • Core Container:核心容器
  • Test:单元测试与集成测试

Spring解决了什么问题?

任何一门技术的出现,肯定不是空穴来风,肯定有他需要解决的业务。

在传统的Java编程中,代码的书写耦合度偏高,我们一般在使用某个类的方法时,我们一般需要先new一个对象,将它实例化,在不那么复杂的业务中,这显得不那么重要,随着业务的迭代和开发的深入,复杂多变的需求开始慢慢侵蚀原本”完美”的架构,我们使用的new方式实例化的对象可能不是那么完美好用了,因为这样的耦合度偏高。

spring的出现,恰好可以解决这个问题,在spring中,我们不要主动去new产生对象,转换为由外部提供对象,并且对象的创建控制权由程序转移到外部,这种思想称为控制反转。

01-spring的核心概念

第一个spring项目

新建项目

01-新建项目20230103-363

导入spring的jar包

在pom.xml添加依赖

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>

右键—>重新加载项目

项目结构

resource资源文件夹下新建一个Spring配置文件,新建—>XML配置文件—>Spring配置—>命名为applicationContext

tips:文件名可随意,但建议使用applicationContext

02-spring – application20230103-514

创建服务类

内容输出测试效果即可

1
2
3
4
5
6
7
package site.hikki.service;

public class BookService {
public void save(){
System.out.println("BookService save...");
}
}

创建bean

resourceapplicationContext.xml配置文件添加以下内容:

1
<bean id="bookService" class="site.hikki.service.BookService"/>

表示创建一个bean对象,对外开放给其他类使用。

创建程序入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package site.hikki;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import site.hikki.service.BookService;

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

// 输出结果:
// BookService save...

项目下载地址:https://rookie1679.lanzoue.com/iMzSZ0jzrb0d

bean的基础配置

配置格式

类别 描述
名称 bean
类型 标签
所属 beans标签
功能 定义Spring核心容器管理的对象
格式 <beans>
<bean/>
<bean></bean>
</beans>
属性 列表 id:bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一 class:bean的类型,即配置的bean的全路径类名
范例 <bean id="BookService" class="site.hikki.service.BookService"/>
<bean id="bookDao" class="site.hikki.dao.bookDao"> </bean>

bean别名配置

类别 描述
名称 name
类型 属性
所属 bean标签
功能 定义bean的别名,可定义多个,使用逗号(,)分号(;)空格( )分隔
范例 <bean id="BookService" name="bookservicee servicebook" class="site.hikki.service.BookService"/>
<bean id="bookDao" name="bookdao,daobook,db" class="site.hikki.dao.bookDao"> </bean>

获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常NoSuchBeanDefinitionExceptionNoSuchBeanDefinitionException: No bean named 'bookDao' available

bean作用范围

类别 描述
名称 scope
类型 属性
所属 bean标签
功能 定义bean的作用范围,可选范围如下
lsingleton:单例(默认)
lprototype:非单例
范例 <bean id="BookService" class="site.hikki.service.BookService" scope="prototype"/>

Spring的生命周期

我们有时候需要在spring的Ioc容器的创建和结束时执行一些业务逻辑,我们需要怎么做呢?

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
├─java
└─site
└─hikki
├─dao
BookDao.java #持久层实现类

└─impl
BookDaoImpl.java # 持久层接口
├─service
BookService.java #业务逻辑实现类

└─impl
BookServiceImpl.java # 业务逻辑接口
App.java
└─resources
applicationContext.xml # spring配置文件

实现方法

BookDao

BookDao接口创建一个save方法。

1
2
3
4
5
package site.hikki.dao;

public interface BookDao {
void save();
}

BookDaoImpl实现BookDao接口的方法,并创建initdestory方法,方法名自定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package site.hikki.dao.impl;

import site.hikki.dao.BookDao;

public class BookDaoImpl implements BookDao {

@Override
public void save() {
System.out.println("BookDaoImpl save ...");
}

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

BookService

BookService接口创建一个save方法。

1
2
3
4
5
package site.hikki.service;

public interface BookService {
void save();
}

BookServiceImpl实现BookService接口的方法。并定义多个接口InitializingBeanDisposableBean,并实现destroyafterPropertiesSet方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package site.hikki.service.impl;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import site.hikki.dao.impl.BookDaoImpl;
import site.hikki.service.BookService;

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
@Override
public void save(){
System.out.println("BookServiceImpl save ...");
}

private BookDaoImpl bookDao;

public void setBookDao(BookDaoImpl bookDao) {
this.bookDao = bookDao;
}

@Override
public void destroy() throws Exception {
System.out.println("destroy");

}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet...");

}
}

在spring配置文件配置bean

1
2
3
4
5
6
7
8
9
10
<?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="site.hikki.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

<bean id="bookService" class="site.hikki.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
  • bean下的property字段中name属性是bookService该bean的对象类属性值,ref属性是引入上面第一个bean的id值,也就是引入上一个bean的对象。

创建程序入口

方法一:手动关闭Ioc容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package site.hikki.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import site.hikki.dao.BookDao;

public class App {
public static void main(String[] args) {
//创建Ioc容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
//方法一:手动关闭Ioc容器
ctx.close();
}
}


//输出结果:
// init ...
// BookDaoImpl save ...
// destory...

从以上结果可以看出,在bean配置init-method和destroy-method属性可以得到spring的声明周期范围。

在虚拟机jvm启动时,Ioc容器会加载bean配置然后启动,如果我们没有手动去关闭Ioc容器,该容器会一直在运行,直到我们手动去关闭它。

需要注意的是,ctx.close();方法一般放在不需要使用到bean之后,不然Ioc提前关闭,后面的bean就没法使用了。

方法二:设置钩子关闭容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package site.hikki.service;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import site.hikki.dao.BookDao;

public class App {
public static void main(String[] args) {
//创建Ioc容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//设置自动关闭Ioc容器钩子
ctx.registerShutdownHook();
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}

// 输出结果:
// init...
// afterPropertiesSet...
// BookDaoImpl save ...
// destroy
// destory...

ctx.registerShutdownHook();设置了Ioc容器自动化关闭钩子,在程序执行时,该方法可以提醒jvm虚拟机在结束时让Ioc容器先关闭再结束jvm虚拟机,并且ctx.registerShutdownHook();不需要考虑方法的位置,放在任何位置都可以。

bean生命周期

  • 初始化容器
    1. 创建对象(内存分配)
    2. 执行构造方法
    3. 执行属性注入(set操作)
    4. 执行bean初始化方法
  • 使用bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行bean销毁方法

bean销毁时机

  • 容器关闭前触发bean销毁
  • 关闭容器方式
    1. 手动关闭容器
      • ConfigurableApplicationContext接口close()操作
    2. 注册关闭钩子,在虚拟机退出前先关闭Ioc容器再退出虚拟机
      • ConfigurableApplicationContext接口registerShutdownHook()操作

项目下载地址:https://rookie1679.lanzoue.com/iLQ810jxkrch

Spring单例模式

spring创建bean对象默认是单例模式的,但我们有时候的业务逻辑需要费单例模式那该怎么办?该案例为你解决这个问题。

单例模式

简单项目介绍

项目沿用上式例子,不需要进行修改,本案例只是用到BookDao接口和BookDaoImpl实现类。

BookDao接口:

1
2
3
4
5
package site.hikki.dao;

public interface BookDao {
void save();
}

BookDaoImpl实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package site.hikki.dao.impl;

import site.hikki.dao.BookDao;

public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("这是构造方法");
}

@Override
public void save() {
System.out.println("BookDaoImpl save ...");
}

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

spring配置文件:

1
<bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>

程序入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package site.hikki.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import site.hikki.dao.BookDao;

public class App {
public static void main(String[] args) {
//创建Ioc容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookDao bookDao = (BookDao) ctx.getBean("bookDao");
BookDao bookDao2 = (BookDao) ctx.getBean("bookDao");

System.out.println(bookDao);
System.out.println(bookDao2);

}
}


// 内容输出:
// 这是构造方法
// init...
// 这是构造方法
// site.hikki.dao.impl.BookDaoImpl@69453e37
// site.hikki.dao.impl.BookDaoImpl@69453e37

从内容输出可以看出来,两次实例化的bookDao和bookDao2都是同一个对象,也可以说是调用的对象都是同一个地址块的对象。

如果我想每次创建的对象都不一样?或者说是每次创建的对象都重新分配一个地址块该如何处理?这就是非单例模式,每次调用的对象都不是同一个。

这时候我们需要使用到实力工厂实例化了,我们之前使用的都是构造方式实例化bean的,每次实例化bean都会调用一次BookDaoImpl实现类的构造方法。

非单例模式

新建一个工厂Bean,isSingleton()方法默认是单例模式,除非你需要设置非单例模式,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package site.hikki.factory;

import org.springframework.beans.factory.FactoryBean;
import site.hikki.dao.BookDao;
import site.hikki.dao.impl.BookDaoImpl;

public class BookDaoFactoryBean implements FactoryBean<BookDao> {
//代替原始实例工厂创建对象的方法
@Override
public BookDao getObject() throws Exception {
return new BookDaoImpl();
}

@Override
public Class<?> getObjectType() {
return BookDao.class;
}

//创建的对象默认是单例模式的(true)
@Override
public boolean isSingleton() {
return false; //true:单例模式 ,false:非单例模式
}
}

spring配置:

1
<bean id="bookDao4" class="site.hikki.factory.BookDaoFactoryBean"/>

程序入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package site.hikki.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import site.hikki.dao.BookDao;

public class App {
public static void main(String[] args) {
//创建Ioc容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookDao bookDao = (BookDao) ctx.getBean("bookDao4");
BookDao bookDao2 = (BookDao) ctx.getBean("bookDao4");

System.out.println(bookDao);
System.out.println(bookDao2);

}
}


// 输出内容:
// 这是构造方法
// 这是构造方法
// site.hikki.dao.impl.BookDaoImpl@65e98b1c
// site.hikki.dao.impl.BookDaoImpl@61322f9d

从打印内容可以看到,两个对象的打印的地址不一样,说说两次创建的对象不是同一个。这就是设置非单例的过程了。

依赖注入

我们平时向一个类中传递数据有有几种方式?

  • 普通方法(set方法)
  • 构造方法

在spring中,依赖注入也是用于传递数据的,而依赖注入也有两种方法传递数据:

  1. setter注入
    • 简单类型(int,String)
    • 引用类型(实体类)
  2. 构造器注入
    • 简单类型(int,String)
    • 引用类型(实体类)

但我们一般都是使用Setter注入较多,下面实验只介绍setter注入方式

项目结构

项目和上面使用的也基本一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
├─java
│ └─site
│ └─hikki
│ ├─dao
│ │ │ BookDao.java
│ │ │
│ │ └─impl
│ │ BookDaoImpl.java
│ ├─service
│ │ │ BookService.java
│ │ │
│ │ └─impl
│ │ BookServiceImpl.java
│ │ App.java <!-- 程序入口 -->
└─resources
│ applicationContext.xml <!-- spring配置文件-->

setter注入

BookServiceImpl实现类:

我们在BookServiceImpl实现类定义几个对象,引用类型、int、String类型,定义三个对象,并且给他们set属性。

为了验证是否拿到数据,我们在该类下的save方法输出值的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package site.hikki.service.impl;

import site.hikki.dao.BookDao;
import site.hikki.service.BookService;

public class BookServiceImpl implements BookService {
private BookDao bookDao;
private int age;
private String name;

public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}

public void setAge(int age) {
this.age = age;
}

public void setName(String name) {
this.name = name;
}

@Override
public void save() {
System.out.println("book service save ..."+name+"年龄:"+ age);
bookDao.save();
}
}

构造器注入

BookDaoImpl实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package site.hikki.dao.impl;

import site.hikki.dao.BookDao;
import site.hikki.service.BookService;

public class BookDaoImpl implements BookDao {

private BookService bookService;
private int age;
private String name;

public BookDaoImpl() {
System.out.println("BookDaoImpl无参构造器");
}

public BookDaoImpl(BookService bookService, int age, String name) {
this.bookService = bookService;
this.age = age;
this.name = name;
}

@Override
public void save() {
System.out.println("BookDaoImpl save ..."+name+"年龄:"+ age);
}

}

构造器注入的关键在于构造器参数的获取,如下:

1
2
3
4
5
public BookDaoImpl(BookService bookService, int age, String name) {
this.bookService = bookService;
this.age = age;
this.name = name;
}

配置bean

你可能会疑问,我们为什么要定义 <bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl"/>???

其实是我们刚刚在BookServiceImpl实现类中定义了一个BookDao的引用类型,我们需要用到bookDao的对象,我们就必须在bean配置他的对象。不然你怎么实例化bookDao对象呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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="bookService" class="site.hikki.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
<property name="name" value="小码同学"/> <!-- 定义值 -->
<property name="age" value="20"/> <!-- 定义值 -->
</bean>
<!-- ref将参数传到BookDaoImpl中-->
<bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl">
<constructor-arg name="bookService" ref="bookService"/>
<constructor-arg name="age" value="22"/><!-- 定义值 -->
<constructor-arg name="name" value="吴小白"/><!-- 定义值 -->
</bean>
</beans>

程序入口

我们实例化用BookService来接收,并且调用save()方法。观察打印结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package site.hikki.service;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
public static void main(String[] args) {
//创建Ioc容器
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}


// 打印结果:
// book service save ...小码同学年龄:20
// BookDaoImpl save ...吴小白年龄:22

从打印结果可以看到,我们在配置文件定义的值可以成功被接收,并且BookDao也被实例化调用了。

1
2
3
4
5
6
7
    <bean id="bookService" class="site.hikki.service.impl.BookServiceImpl">
<!-- <property name="bookDao" ref="bookDao"/>-->
<property name="name" value="小码同学"/>
<property name="age" value="20"/>
</bean>
<!-- ref将参数传到BookDaoImpl中-->
<bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl"/>

留下个小问题?你试试将bookDao的属性注释掉再重新运行试试,去了解一下为什么会这样

原因解释

<property name="bookDao" ref="bookDao"/>没有传递BookDao的参数时,在BookServiceImpl的实现类下的save方法中,存在bookDao.save();,它表示准备调用BookDao接口的save()方法,但是调用时,bean配置没有给他实例化啊,为什么没有实例化?

原因刚刚把<property name="bookDao" ref="bookDao"/>注释掉了,这段代码的作用就是给他实例化对象。

项目下载地址:https://rookie1679.lanzoue.com/iIhT10jzljdi

依赖自动装配

使用方法

在上一节,我们讲到依赖注入的问题,我们需要配置一个引用类型的参数才能在bookService调用BookDao的方法,但每次都要配置,感觉好麻烦啊,有没有什么方法可以让他帮我自己识别,自动帮我装配传参过去呢?

1
2
3
4
5
    <bean id="bookService" class="site.hikki.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/> <!-- 配置该引用类型 -->
</bean>
<!-- ref将参数传到BookDaoImpl中-->
<bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl"/>

答案是:有的,spring有有一个自动装配的方法,添加autowire属性,该属性有五个值:

  1. byType(根据类型自动装配)
  2. byName(根据名称自动装配)
  3. constructor(使用构造方法自动装配)
  4. default(使用默认)
  5. no(不使用自动装配)

这个根据类型和名称是BookServiceImpl下的setBookDao方法的那个名称,比如该方法的名称就是bookDao根据该名称自动装配,根据该类型自动装配。

1
2
3
<bean id="bookService" class="site.hikki.service.impl.BookServiceImpl" autowire="byType"/>
<!-- ref将参数传到BookDaoImpl中-->
<bean id="bookDao" class="site.hikki.dao.impl.BookDaoImpl"/>

依赖自动装配特征

  • 自动装配用于引用类型依赖注入,不能对简单的类型进行操作。
  • 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用。
  • 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名和配置耦合,不推荐使用。
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效。

集合注入

集合注入用的不多,一般用于一些项目的初始化,但也很少用到,用的最多

DataService方法实现

我们在DataService定义几个属性,类型都是集合。

然后在spring配置文件添加初始化的值,进行注入。

定义属性后,记得给他们设置set方法,并且再定义一个save方法打印值的输出,用于检验值是否成功注入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.util.*;

public class DataService {
private int[] arrayInt;
private List<String> listStr;
private Set<String> setStr;
private Map<String,String> mapStr;
private Properties propertiesStr;

public void setArrayInt(int[] arrayInt) {
this.arrayInt = arrayInt;
}

public void setListStr(List<String> listStr) {
this.listStr = listStr;
}

public void setSetStr(Set<String> setStr) {
this.setStr = setStr;
}

public void setMapStr(Map<String, String> mapStr) {
this.mapStr = mapStr;
}

public void setPropertiesStr(Properties propertiesStr) {
this.propertiesStr = propertiesStr;
}

public void save(){
System.out.println("DataService...");
System.out.println("遍历数组arrayInt:"+ Arrays.toString(arrayInt));
System.out.println("遍历数组listStr:"+listStr.toString());
System.out.println("遍历数组setStr:"+setStr.toString());
System.out.println("遍历数组mapStr:"+mapStr.toString());
System.out.println("遍历数组propertiesStr:"+propertiesStr.toString());
}
}

spring配置

定义一个bean,该bean指定DataService类,添加子标签property,定义集合数据,其中property标签的name的值应该为注入DataService对象的属性。

重点学习:

  1. List
  2. Map
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?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="dataService" class="DataService">
<!-- 数据初始化 注入-->
<property name="arrayInt">
<array>
<value>100</value>
<value>200</value>
<value>300</value>
</array>
</property>
<property name="listStr">
<!-- 重点-->
<list>
<value>小码同学</value>
<value>小码博客</value>
<value>小码公众号</value>
</list>
</property>
<property name="mapStr">
<!-- 重点-->
<map>
<entry key="name" value="小码同学"/>
<entry key="blog" value="https://blog.hikki.site"/>
<entry key="weixin" value="小码同学"/>
</map>
</property>
<property name="setStr">
<set>
<value>小码同学</value>
<value>小码博客</value>
<value>小码公众号</value>
</set>
</property>
<property name="propertiesStr">
<props>
<prop key="name">小码同学</prop>
<prop key="blog">小码博客</prop>
<prop key="weixin">小码公众号</prop>
</props>
</property>
</bean>
</beans>

程序入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.ApplicationContext;

public class App {

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



// 结果输出:
// DataService...
// 遍历数组arrayInt:[100, 200, 300]
// 遍历数组listStr:[小码同学, 小码博客, 小码公众号]
// 遍历数组setStr:[小码同学, 小码博客, 小码公众号]
// 遍历数组mapStr:{name=小码同学, blog=https://blog.hikki.site, weixin=小码同学}
// 遍历数组propertiesStr:{weixin=小码公众号, name=小码同学, blog=小码博客}

由结果可以看到集合已经注入成功。

项目下载:https://rookie1679.lanzoue.com/iJ1xF0k0txra

spring的基础已经学习了差不多啦,继续加油!!!