SSM学习之Spirngday02
创始人
2025-05-28 19:33:58

1,IOC/DI配置管理第三方bean

前面所讲的知识点都是基于我们自己写的类,现在如果有需求让我们去管理第三方jar包中的类,该如何管理?
核心容器我们已经学了好多知识了 bean的管理 依赖注入的管理 我们现在管理大部分是自己创造的类和对象 如果是第三方提供的类和对象 如何管理是我们要解决的问题
解决的问题就是第三方提供的bean对象的管理

1.1 案例:数据源对象管理

在这一节中,我们将通过一个案例来学习下对于第三方bean该如何进行配置管理。

以后我们会用到很多第三方的bean,本次案例将使用咱们前面提到过的数据源Druid(德鲁伊)C3P0来配置学习下。

1.1.1 环境准备

学习之前,先来准备下案例环境:

在这里插入图片描述

1.1.2 思路分析

在上述环境下,我们来对数据源进行配置管理,先来分析下思路:

需求:使用Spring的IOC容器来管理Druid连接池对象

1.使用第三方的技术,需要在pom.xml添加依赖

2.在配置文件中将【第三方的类】制作成一个bean,让IOC容器进行管理

3.数据库连接需要基础的四要素驱动连接用户名密码,【如何注入】到对应的bean中

4.从IOC容器中获取对应的bean对象,将其打印到控制台查看结果

思考:

  • 第三方的类指的是什么?
  • 如何注入数据库连接四要素?

1.1.3 实现Druid管理

带着这两个问题,把下面的案例实现下:

步骤1:导入druid的依赖

pom.xml中添加依赖

com.alibabadruid1.1.16

步骤2:配置第三方bean

看源码和配置文件就知道是setter注入,因为底层源码中构造方法就两个根本就无法构造器注入。

在applicationContext.xml配置文件中添加DruidDataSource的配置




说明:**

  • driverClassName:数据库驱动
  • url:数据库连接地址
  • username:数据库连接用户名
  • password:数据库连接密码
  • 数据库连接的四要素要和自己使用的数据库信息一致。
步骤3:从IOC容器中获取对应的bean对象
public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");DataSource dataSource = (DataSource) ctx.getBean("dataSource");System.out.println(dataSource);}
}
步骤4:运行程序

打印如下结果: 说明第三方bean对象已经被spring的IOC容器进行管理
在这里插入图片描述
做完案例后,我们可以将刚才思考的两个问题答案说下:

  • 第三方的类指的是什么?

    DruidDataSource
    
  • 如何注入数据库连接四要素?

    setter注入
    

1.2 加载properties文件

上节中我们已经完成两个数据源druidC3P0的配置,但是其中包含了一些问题,我们来分析下:

  • 这两个数据源中都使用到了一些固定的常量如数据库连接四要素,把这些值写在Spring的配置文件中不利于后期维护
  • 需要将这些值提取到一个外部的properties配置文件中
  • Spring框架如何从配置文件中读取属性值来配置就是接下来要解决的问题。

问题提出来后,具体该如何实现?

1.2.1 第三方bean属性优化

1.2.1.1 实现思路

需求:将数据库连接四要素提取到properties配置文件,spring来加载配置信息并使用这些信息来完成属性注入。

1.在resources下创建一个jdbc.properties(文件的名称可以任意)

2.将数据库连接四要素配置到配置文件中

3.在Spring的配置文件中加载properties文件

4.使用加载到的值实现属性注入

其中第3,4步骤是需要大家重点关注,具体是如何实现。

1.2.1.2 实现步骤
步骤1:准备properties配置文件

resources下创建一个jdbc.properties文件,并添加对应的属性键值对

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root
步骤2:开启context命名空间
在applicationContext.xml中开`context`命名空间



步骤3:加载properties配置文件

在配置文件中使用context命名空间下的标签来加载properties配置文件


步骤4:完成属性注入

使用${key}来读取properties配置文件中的内容并完成属性注入




至此,读取外部properties配置文件中的内容就已经完成。

1.2.2 读取单个属性

1.2.2.1 实现思路

对于上面的案例,效果不是很明显,我们可以换个案例来演示下:

需求:从properties配置文件中读取key为name的值,并将其注入到BookDao中并在save方法中进行打印。

1.在项目中添加BookDao和BookDaoImpl类

2.为BookDaoImpl添加一个name属性并提供setter方法

3.在jdbc.properties中添加数据注入到bookDao中打印方便查询结果

4.在applicationContext.xml添加配置完成配置文件加载、属性注入(${key})

1.2.2.2 实现步骤
步骤1:在项目中添对应的类

BookDao和BookDaoImpl类,并在BookDaoImpl类中添加name属性与setter方法

public interface BookDao {public void save();
}public class BookDaoImpl implements BookDao {private String name;public void setName(String name) {this.name = name;}public void save() {System.out.println("book dao save ..." + name);}
}
步骤2:完成配置文件的读取与注入

在applicationContext.xml添加配置,bean的配置管理读取外部properties依赖注入:




步骤3:运行程序

在App类中,从IOC容器中获取bookDao对象,调用方法,查看值是否已经被获取到并打印控制台

public class App {public static void main(String[] args) throws Exception{ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}

在这里插入图片描述

1.2.2.3 注意事项

至此,读取properties配置文件中的内容就已经完成,但是在使用的时候,有些注意事项:

  • 问题一:键值对的key为username引发的问题

    1.在properties中配置键值对的时候,如果key设置为`username

  username=root666

2.在applicationContext.xml注入该属性




3.运行后,在控制台打印的却不是root666,而是自己电脑的用户名
4.出现问题的原因是标签会加载系统的环境变量,而且环境变量的值会被优先加载,如何查看系统的环境变量?

5.解决方案



system-properties-mode:设置为NEVER,表示不加载系统属性,就可以
解决上述问题。
当然还有一个解决方案就是避免使用username作为属性的key。
问题二:当有多个properties配置文件需要被加载,该如何配置?
1.调整下配置文件的内容,在resources下添加
jdbc.properties,jdbc2.properties,内容如下:
jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root

jdbc2.properties

username=root666

2.修改applicationContext.xml



	

方式一:可以实现,如果配置文件多的话,每个都需要配置
方式二:*.properties代表所有以properties结尾的文件都会
被加载,可以解决方式一的问题,但是不标准
方式三:标准的写法,classpath:代表的是从根路径下开始查
找,但是只能查询当前项目的根路径
方式四:不仅可以加载当前项目还可以加载当前项日所依赖的
所有项目的根路径下的properties配置文件

1.2.3 加载properties文件小结

本节主要讲解的是properties配置文件的加载,需要掌握的内容有:

  • 如何开启context命名空间
  • 如何开启`context`命名空间 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5d7f720da9224d5ba30382cf7609a9bc.png) 如何加载properties配置文件

如何在applicationContext.xml引入properties配置文件中的值

${key}

2,核心容器

前面已经完成bean与依赖注入的相关知识学习,接下来我们主要学习的是IOC容器中的核心容器

这里所说的核心容器,大家可以把它简单的理解为ApplicationContext,前面虽然已经用到过,但是并没有系统的学习,接下来咱们从以下几个问题入手来学习下容器的相关知识:

  • 如何创建容器?
  • 创建好容器后,如何从容器中获取bean对象?
  • 容器类的层次结构是什么?
  • BeanFactory是什么?

2.1 环境准备

在学习和解决上述问题之前,先来准备下案例环境:

  • 创建一个Maven项目

  • pom.xml添加Spring的依赖

  • 在这里插入图片描述
    resources下添加applicationContext.xml




添加BookDao和BookDaoImpl类

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

创建运行类App

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

2.2 容器

2.2.1 容器的创建方式

案例中创建ApplicationContext的方式为:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

这种方式翻译为:类路径下的XML配置文件

除了上面这种方式,Spring还提供了另外一种创建方式为:

ApplicationContext ctx = new FileSystemXmlApplicationContext("applicationContext.xml");

这种方式翻译为:文件系统下的XML配置文件

使用这种方式,运行,会出现如下错误:
在这里插入图片描述
从错误信息中能发现,这种方式是从项目路径下开始查找applicationContext.xml配置文件的,所以需要将其修改为:
在这里插入图片描述
说明:**大家练习的时候,写自己的具体路径。

这种方式虽能实现,但是当项目的位置发生变化后,代码也需要跟着改,耦合度较高,不推荐使用。

2.2.2 Bean的三种获取方式

方式一,就是目前案例中获取的方式:

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

这种方式存在的问题是每次获取的时候都需要进行类型转换,有没有更简单的方式呢?

方式二:

BookDao bookDao = ctx.getBean("bookDao",BookDao.class);

这种方式可以解决类型强转问题,但是参数又多加了一个,相对来说没有简化多少。

方式三:

BookDao bookDao = ctx.getBean(BookDao.class);

这种方式就类似我们之前所学习依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个。

2.2.3 容器类层次结构

(1)在IDEA中双击shift,输入BeanFactory
在这里插入图片描述
(2)点击进入BeanFactory类,ctrl+h,就能查看到如下结构的层次关系
在这里插入图片描述
就是configurableApplicationContext 提供close关闭的方法
从图中可以看出,容器类也是从无到有根据需要一层层叠加上来的,大家重点理解下这种设计思想。

2.2.4 BeanFactory的使用

使用BeanFactory来创建IOC容器的具体实现方式为:

public class AppForBeanFactory {public static void main(String[] args) {Resource resources = new ClassPathResource("applicationContext.xml");BeanFactory bf = new XmlBeanFactory(resources);BookDao bookDao = bf.getBean(BookDao.class);bookDao.save();}

为了更好的看出BeanFactoryApplicationContext之间的区别,在BookDaoImpl添加如下构造函数:

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

在这里插入图片描述
在这里插入图片描述

对于BeanFactory如果没有调用getBean方法 bean对象都不会被创建

如果不去获取bean对象,打印会发现:

  • BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建

  • ApplicationContext是立即加载,容器加载的时候就会创建bean对象

  • ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置

  • 设置lazy-init="true"之后bean对象就不会在容器加载的时候创建bean对象而是和beanFactory一样没调用getbean方法之前都不会创建bean对象

 


小结**

这一节中所讲的知识点包括:

  • 容器创建的两种方式

    • ClassPathXmlApplicationContext[掌握]
    • FileSystemXmlApplicationContext[知道即可]
  • 获取Bean的三种方式

    • getBean(“名称”):需要类型转换
    • getBean(“名称”,类型.class):多了一个参数
    • getBean(类型.class):容器中不能有多个该类的bean对象

    上述三种方式,各有各的优缺点,用哪个都可以。

  • 容器类层次结构

    • 只需要知晓容器的最上级的父接口为 BeanFactory即可
  • BeanFactory

    • 使用BeanFactory创建的容器是延迟加载
    • 使用ApplicationContext创建的容器是立即加载
    • 具体BeanFactory如何创建只需要了解即可。
    • 2.2 核心容器总结

这节中没有新的知识点,只是对前面知识的一个大总结,共包含如下内容:

2.2.1 容器相关

  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
  • ApplicationContext接口常用初始化类
    • ClassPathXmlApplicationContext(常用)
    • FileSystemXmlApplicationContext

2.2.2 bean相关

在这里插入图片描述
其实整个配置中最常用的就两个属性idclass

把scope、init-method、destroy-method框起来的原因是,后面注解在讲解的时候还会用到,所以大家对这三个属性关注下。

2.2.3 依赖注入相关

在这里插入图片描述

相关内容

热门资讯

实测分享“新全游到底有没有透视... 您好:新全游这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在新全游这款游...
科技通报“汇友炸金花到底有挂吗... 亲.汇友炸金花这款游戏是可以开挂的,确实是有挂的,通过添加客服【3671900】很多玩家在这款游戏中...
玩家必备攻略“ 奇迹联盟有挂吗... 您好:奇迹联盟这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5537821】很多玩家在这款游戏...
实测分享“518乐游真的有挂是... 您好:518乐游这款游戏可以开挂,确实是有挂的,需要软件加微信【8700483】,很多玩家在518乐...
今日热点.微乐四川麻将有没有挂... 亲.微乐四川麻将这款游戏是可以开挂的,确实是有挂的,通过添加客服【9307068】很多玩家在这款游戏...