【spring系列】2-资源加载

加载properties文件

我们链接数据库时,我们一般都使用一个properties文件来存储我们的连接数据信息,接下来我们使用bean来管理我们的properties文件资源。

添加依赖

在加载properties文件时,需要一个数据库连接池来管理我们的数据库,我们选择阿里巴巴的Druid连接池。

数据库我们选择MariaDB数据库。打开pom.xml文件,添加依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.1.0</version>
</dependency>

配置bean

在添加bean前,我们需要新建一个context命名空间,在applicationContext.xml文件中添加命名空间。

  1. xmlns="http://www.springframework.org/schema/beans"复制为新的URL,并在``=号前加上:context,又将后面beans修改为context`。
    • 得到这样的xmlns:context="http://www.springframework.org/schema/context"
  2. 将修改后的URL地址(http://www.springframework.org/schema/context)添加到xsi:schemaLocation中,URL之间用空格或者换行分隔开。
  3. xsi:schemaLocation的地址中的http://www.springframework.org/schema/beans/spring-beans.xsd复制为新的URL,并将含有beans更改为context
    • 得到这样的http://www.springframework.org/schema/context/spring-context.xsd

01-加载properties-spring – spring4-day20230103-216

修改前:

1
2
3
4
5
<?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">
</beans>

修改后:

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:conteext="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1. 开启一个context命名空间-->
<!-- 2.使用context空间加载properties-->
<context:property-placeholder location="db.properties"/>
</beans>

添加一个context命名空间的标签,并且加载db.properties文件。

添加Druid的bean管理

刚刚我们导入了阿里巴巴的Druid包,现在用上啦。记得添加上数据的连接对象所需要的的值:

  • driverClassName
  • url
  • username
  • password
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<!-- 1. 开启一个context命名空间-->
<!-- 2.使用context空间加载properties-->
<context:property-placeholder location="db.properties"/>
<!-- 3.使用${}读取db.properties文件的变量值-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>

注意事项

问题一:

有些同学喜欢将value的值设置为${username}这种形式,这种形式可能会出问题,因为spring读取username变量时,系统如果存在username变量,会优先读取系统的username变量。

解决方法:在context标签加上system-properties-mode="NEVER"表示不读取系统变量。

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

问题二:

如果我们有多个properties文件怎么办?我们怎么读取多个文件,我们可以用,逗号分隔开多个文件,表示多个文件一起读取。

1
<context:property-placeholder location="db.properties,msg.properties"/>

如果文件有非常多,可以用通配符*匹配全部properties后缀的文件。

1
<context:property-placeholder location="*.properties"/>

标准加载properties文件格式

加载properties文件:(不包括导入的jar包properties文件)

1
<context:property-placeholder location="classpath:*.properties"/>

加载properties文件:(包括导入的jar包中properties文件)

1
<context:property-placeholder location="classpath*:*.properties"/>

classpath后多加一个*号匹配jar包中的properties文件。

新建properties文件

urlusernamepassword根据你自己的情况修改,我的MariaDB的端口,我改成了3307。

1
2
3
4
jdbc.driver=org.mariadb.jdbc.Driver
jdbc.url=jdbc:mariadb://127.0.0.1:3307/spring_db
jdbc.username=root
jdbc.password=root

测试是否读取成功

创建一个App.java类,按照以往正常的spring项目即可,打印一下返回结果。

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

public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}


//输出结果:
// {
// CreateTime:"2023-01-03 23:13:46",
// ActiveCount:0,
// PoolingCount:0,
// CreateCount:0,
// DestroyCount:0,
// CloseCount:0,
// ConnectCount:0,
// Connections:[
// ]
//}

出现以上结果表示读取properties文件成功了。

容器、Bean

本节内容作了解即可

创建容器的方式

方式一:类路径加载配置文件

我们常用的创建Ioc容器的方式

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

方式二:文件路径加载配置文件

1
ApplicationContext ctx = new FileSystemXmlApplicationContext("E:\Cache\Java\demo\spring\spring\spring4-day2\src\main\resources\applicationContext.xml");

方式三:加载多个配置文件

1
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");

获取bean

方式一:使用bean名称获取

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

方式二:使用bean名称获取并指定类型

其实就是将强制转换的类型放在了后面而已,指定该bean对应的class

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

方式三:使用bean类型获取

直接自动装配的话,有一定缺点。

如果在bean文件里面有多个BookDao的bean就会报错,因为没有指定id或者name值,系统不知道应该给哪一个自动装配。

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

BeanFactory初始化

spring的老版本加载Bean的方式

在加载applicationContext.xml时,使用的是XmlBeanFactory()方法,这样的加载会有延迟。

1
2
3
4
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean("bookDao", BookDao.class);
bookDao.save();

Q:什么是延迟加载?

A:applicationContext.xml文件都有一些bean的配置,每一个bean都有对应的类,每个类都有默认的构造方法,如果使用最新版的spring项目,每次项目启动时,会自动加载bean对应的类的构造方法。

如果使用旧版的spring,使用XmlBeanFactory()方式加载就会延迟加载,bean对应的类就不会加载对应的构造方法。

Q:如果我想在最新版的spring项目使用延迟加载怎么办?

A:spring也有对应的方式设置延迟加载,在你需要的bean上,添加``lazy-init=“true”`属性即可,表示该bean会延迟加载,在初始化重启时不会加载该bean对应的类构造方法。

容器相关

  • BeanFactory是IoC:容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载

  • ApplicationContext:接口是Spring容器的核心接口,初始化时bean立即加载

  • ApplicationContext:接口提供基础的bean操作相关方法,通过其他接口扩展其功能

  • ApplicationContext:接口常用初始化类(加载applicationContext.xml)

    • ClassPathXmlApplicationContext:使用类加载方法xml文件(直接获取到resource文件夹的资源)
    • FileSystemXmlApplicationContext:使用系统资源管理器加载(也就是使用绝对路径方式加载xml文件)

Bean相关

属性=值 备注
id=“bookDao” bean的Id
name=“dao bookDaoImpl daoImpl” bean别名
class=“com.itheima.dao.impl.BookDaoImpl” bean类型,静态工厂类,FactoryBean类
scope=“singleton” 控制bean的实例数量
init-method=“init” 生命周期初始化方法
destroy-method=“destory” 生命周期销毁方法
autowire=“byType” 自动装配类型
factory-method=“getInstance” bean工厂方法,应用于静态工厂或实例工厂
factory-bean=“com.itheima.factory.BookDaoFactory” 实例工厂bean
lazy-init=“true” 控制bean延迟加载
1
2
3
4
5
6
7
8
9
10
11
12
<bean    
id="bookDao"
name="dao bookDaoImpl daoImpl"
class="com.itheima.dao.impl.BookDaoImpl"
scope="singleton"
init-method="init"
destroy-method="destory"
autowire="byType"
factory-method="getInstance"
factory-bean="com.itheima.factory.BookDaoFactory"
lazy-init="true"
/>

依赖注入相关

属性 备注
<constructor-arg name="bookDao" ref="bookDao"/> 构造器注入引用类型
<constructor-arg name="userDao" ref="userDao"/> 构造器注入引用类型
<constructor-arg name="msg" value="WARN"/> 构造器注入简单类型
<constructor-arg type="java.lang.String" index="3" value="WARN"/> 类型匹配与索引匹配
<property name="bookDao" ref="bookDao"/> setter注入引用类型
<property name="userDao" ref="userDao"/>
<property name="msg" value="WARN"/> setter注入引用类型
<property name="names"> setter注入引用类型
<list> list集合
<value>itcast</value> 集合注入简单类型
<ref bean="dataSource"/> 集合注入引用类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"> 
<constructor-arg name="bookDao" ref="bookDao"/>
<constructor-arg name="userDao" ref="userDao"/>
<constructor-arg name="msg" value="WARN"/>
<constructor-arg type="java.lang.String" index="3" value="WARN"/>
<property name="bookDao" ref="bookDao"/>
<property name="userDao" ref="userDao"/>
<property name="msg" value="WARN"/>
<property name="names">
<list>
<value>itcast</value>
<ref bean="dataSource"/
</list>
</property>
</bean>

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

常用的context命名空间

可以直接复制去用

1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">



</beans>