Spring | 数据源对象 properties文件 创建容器和获取bean 容器总结

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: Spring | 数据源对象 properties文件 创建容器和获取bean 容器总结

一、前言


这篇文章主要介绍


1. spring中如何在配置文件applicationContext.xml中配置外部数据源对象的bean

2. 如何加载配置文件到applicationContext.xml中使用


二、内容


1.数据源对象管理


构造DruidDataSource对象


第一步:在pom.xml中导入druid连接池的坐标


<!--        druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.0</version>
        </dependency>


第二步:在applicationContext.xml文件中构造bean对象


<!--    管理druid-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<!--        setter注入-->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<!--        注入驱动类名-->
        <property name="url" value="mysql:jdbc://localhost:3306/daily?useSSL=false"/>
<!--        注入url-->
        <property name="username" value="root"/>
<!--        注入数据库用户名和密码-->
        <property name="password" value="@123456"/>
    </bean>


第三步:获取spring构造出来的对象


public class DruidApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //加载配置文件
        DruidDataSource dataSource = (DruidDataSource) context.getBean("dataSource"); //获取druid数据源对象
        System.out.println(dataSource); //druid
    }
}


第四步:查看运行结果


{
  CreateTime:"2022-12-27 09:27:31",
  ActiveCount:0,
  PoolingCount:0,
  CreateCount:0,
  DestroyCount:0,
  CloseCount:0,
  ConnectCount:0,
  Connections:[
  ]
}


在控制台打印了如上信息,以上属性都是可以在applicationContext.xml中注入的。


构造ComboPooledDataSource对象


这个构造和druid很类似,因为同样是获取数据源对象,只是这个类中属性的名字不一样,请看代码。


<!--    管理c3p0对象-->
    <bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!--        注入驱动类名-->
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
        <!--        注入url-->
        <property name="jdbcUrl" value="mysql:jdbc://localhost:3306/daily?useSSL=false"/>
        <!--        数据库用户名和密码-->
        <property name="user" value="root"/>
        <property name="password" value="@123456"/>
        <property name="maxConnectionAge" value="200"/>
    </bean>


可以看到驱动类名的属性,url,用户名和druid是不同的,这是我们要注意的地方,其他步骤一致,下面请看运行结果。


com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 3


上面只截取了一部分

注意看上面这种创建数据源对象的方式,把和数据库有关的信息都放在xml文件里了,这样的代码冗余度和耦合度很高。


因此,主流的写法是把这些连接信息放在properties文件中,在applicationContext.xml中加载这个properties文件,从而获取相关信息。


2.加载properties文件


步骤


第一步:在applicationContext.xml中开启context命名空间

a82fb195e5f34c65b6437447e0ea108b.png


第二步:使用context命名空间加载properties配置文件


<!--    第二步:使用context命名空间加载properties文件-->
    <context:property-placeholder location="jdbc.properties"/>

第三步:使用${}读取配置文件里的属性值


<bean id="dataS" class="com.alibaba.druid.pool.DruidDataSource">
<!--        第三步:使用${}读取属性值-->
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${username}"/>
<!--        当系统变量名和配置文件中属性名重名时,可以关闭系统模式-->
        <property name="password" value="${jdbc.password}"/>
    </bean>


注意事项


1.加载多个配置文件使用逗号隔开


<context:property-placeholder location="jdbc.properties,jdbc2.properties"/>



2.使用$ {}获取值时如果系统变量名和属性名重名,要关闭系统属性模式

例如 $ {username}获取到的是电脑用户名,而不是配置文件里的username值


1b2b3cfe502c4afaa4af5a716cd51ed5.png


public class PropertiesApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //加载配置文件
        DruidDataSource dataSource = (DruidDataSource) context.getBean("dataS");
        System.out.println(dataSource.getPassword()); //获取数据库密码
        System.out.println(dataSource.getUsername()); //获取数据库用户名
    }
}

运行结果

e6458b54d9b646a28e8bb04e94019319.png


关闭系统属性模式:


<context:property-placeholder location="jdbc.properties,jdbc2.properties" system


3.使用通配符*加载所有配置文件


    <context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>


4.规范化写法


    <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>

5.连同jar包中的配置文件一起加载


    <context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

总结:


240f52c0239f4b96b1403f558a75ceb7.png


3.容器


创建context容器的三种方式


1.通过ClassPathXmlApplicationContext创建,参数是spring的配置文件名


ApplicationContext context = new ClassPathXmlApplicationContext("app_2.xml");



2.通过FileSystemXmlApplicationContext创建,参数是配置文件在本机上的绝对路径


ApplicationContext context = new FileSystemXmlApplicationContext("F:\\Codes\\vacation\\ssm


3.加载多个配置文件,有多少个配置文件就写几个参数


ApplicationContext context1 = new ClassPathXmlApplicationContext("app_2.xml", "applicationC


获取bean的三种方式


1.id+强转


UserDao dao = (UserDao) context.getBean("userDao");

2.id+类型


UserDao userDao = context.getBean("userDao", UserDao.class);

3.类型(前提是配置文件中该类型的bean唯一,否则报错)


UserDao bean = context.getBean(UserDao.class);


报错示例


<bean class="dao.impl.UserDaoImpl" id="userDao" lazy-init="true"/>
 <bean class="dao.impl.UserDaoImpl" id="userDao1"/>

16d6e127d95f42f9a091cbdb5fa18439.png

bf487cd1623b48ba8da14919db667d99.png

如图中,存在两个UserDaoImpl的bean,通过类型获取,就产生了报错。


使用BeanFactory和ApplicationContext获取bean的对比


public class App_2 {
    public static void main(String[] args) {
        Resource resource = new ClassPathResource("app_2.xml");
        BeanFactory factory = new XmlBeanFactory(resource); //早期通过BeanFactory的方式获取bean
        UserDao bean = factory.getBean("userDao", UserDao.class);
        bean.say();
    }
}


运行结果

0dfaaf2299064857871e2701b86cee68.png

首先看构造方法

62494a5f19bf48b8a74969dded4737ca.png

注意看下面的对比

13f92cbbc9c34ff591a94b92b4bc8c82.png

BeanFactory这里只有两行代码的运行结果

7e46abd46c3e4f9bb01f4178250722d5.png

运行结果为空

655c200177ce480592e0f0bc2f626644.png

运行结果调用了构造方法

463f202972d34729ab063edce5833292.png

因此,使用BeanFactory和ApplicationContext获取容器的区别是创建bean的时机不同,

前者是延迟加载,在getBean()时才创建;后者是立即加载,在ApplicationContext对象创建好的时候就创建好了bean

当然也可以设置ApplicationContext为延迟加载。

49a882a4a0944385932cbbffcb675fc9.png

4.核心容器总结


容器相关


BeanFactory ApplicationContext
容器最底层的接口 实现自该接口
延迟加载bean 立即加载bean

bean相关


0211c63295bf4ec99c5afb94dd429320.png


依赖注入相关

9e4655e90b1444f48e21106d65e27726.png


总结:


构造器注入 setter注入
使用constructor标签 使用property标签
name写属性名 name写属性名
简单类型(但包括string)用value 引用类型用ref


三、结语


这篇文章主要介绍了如何在配置文件中创建外部数据源对象,加载和使用properties文件,创建容器和获取bean的三种方式并对之前的一些知识点做了总结,后续会补充关于集合注入和自动装配的知识。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
1月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
38 1
|
1月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
110 2
|
1月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
28 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
1月前
|
前端开发 Docker 容器
主机host服务器和Docker容器之间的文件互传方法汇总
Docker 成为前端工具,可实现跨设备兼容。本文介绍主机与 Docker 容器/镜像间文件传输的三种方法:1. 构建镜像时使用 `COPY` 或 `ADD` 指令;2. 启动容器时使用 `-v` 挂载卷;3. 运行时使用 `docker cp` 命令。每种方法适用于不同场景,如静态文件打包、开发时文件同步及临时文件传输。注意权限问题、容器停止后的文件传输及性能影响。
130 0
|
1月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
65 0
|
2月前
|
XML Java 开发者
经典面试---spring IOC容器的核心实现原理
作为一名拥有十年研发经验的工程师,对Spring框架尤其是其IOC(Inversion of Control,控制反转)容器的核心实现原理有着深入的理解。
120 3
|
3月前
|
关系型数据库 MySQL 应用服务中间件
[Docker]容器内文件修改
【8月更文挑战第21天】[Docker]容器内文件修改
169 13