@[TOC]
第三方资源配置管理
前面我们IOC容器中装的都是我们自己写的类,现在我们尝试去管理第三方jar包中的类。此处我们就拿alibaba的druid来做例子:
首先我们先引入它的依赖坐标(在项目的配置pom文件中):
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
如果你不是很确定这个坐标该怎么引入,那么我们可以借助一个网站: mvnrepository.com:
我们可以直接搜索我们想引入坐标的关键词,例如druid,搜索结果显示的第一个就是:
然后我们点进去选择一个版本,在这里我选择一个使用人数多的:
点进去之后我们就可以看到相关的依赖坐标了:
在引入完坐标之后,我们在Spring的配置文件中直接进行第三方的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">
<!--管理DruidDataSource对象-->
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="*********"/>
<!--此处填写自己的用户名以及密码-->
</bean>
</beans>
我们这里配置的第三方的类是DruidDataSource
说明:
- driverClassName:数据库驱动
- url:数据库连接地址
- username:数据库连接用户名
- password:数据库连接密码
- 数据库连接的四要素要和自己使用的数据库信息一致。
然后我们验证一下是否配置成功:
public class App4 {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext1.xml");
DataSource druid = (DataSource) ctx.getBean("druid");
System.out.println(druid);
}
}
结果为:
这说明配置成功!
这里要注意我们使用构造器依赖注入还是setter依赖注入,我们不是凭空的去猜测,而是根据这个第三方资源的内部结构来决定的,我们现在可以来看一看DruidDataSource类的结构:
我们可以初步发现构造方法只有两个,且一个是空参另一个是布尔值,那么这也就意味着我们不能使用构造器进行依赖注入。接下来我们进行关键字检索,发现其中的set方法是满足我们的需求的:
所以我们这里果断选择使用setter进行依赖注入!
注意:
- 数据连接池在配置属性的时候,除了可以注入数据库连接四要素外还可以配置很多其他的属性,具体都有哪些属性用到的时候再去查,一般配置基础的四个,其他都有自己的默认值
- Druid和C3P0在没有导入mysql驱动包的前提下,一个没报错一个报错,说明Druid在初始化的时候没有去加载驱动,而C3P0刚好相反
- Druid程序运行虽然没有报错,但是当调用DruidDataSource的getConnection()方法获取连接的时候,也会报找不到驱动类的错误
- 如果报错的时候显示的是==ClassNotFoundException==,翻译出来是
类没有发现的异常
,具体的类为com.mysql.jdbc.Driver
。错误的原因是缺少mysql的驱动包。我们在项目的pom文件中添加驱动坐标即可。
加载properties文件
刚才我们完成了druid的配置,但是其中包含了一些问题:在druid中我们使用到了一些固定的常量如数据库连接四要素,把这些值写在Spring的配置文件中不利于后期维护。
我们需要将这些值提取到一个外部的properties配置文件中,Spring框架如何从配置文件中读取属性值来配置就是接下来要解决的问题。
基本步骤
步骤1:resources下创建一个jdbc.properties文件,并添加对应的属性键值对
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis
jdbc.username=root
jdbc.password=******
步骤2:开启context
命名空间
在applicationContext.xml中开context
命名空间
<?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:xsi="http://www.w3.org/2001/XMLSchema-instance"复制一份,再将xsi修改即可-->
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">
</beans>
注意:修改部分别遗漏
步骤3:加载properties配置文件
在配置文件中使用context
命名空间下的标签来加载properties配置文件
<context:property-placeholder location="jdbc.properties"/>
步骤4:完成属性注入
使用${key}
来读取properties配置文件中的内容并完成属性注入
<?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">
<context:property-placeholder location="jdbc.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>
至此,读取外部properties配置文件中的内容就已经完成。
注意事项
问题一:键值对的key为username
引发的问题
1.在properties中配置键值对的时候,如果key设置为username
username=root666
2.这个时候如果你在配置文件中使用,其实它对应的并不是root666:
<property name="username" value="${username}"/>
3.出现问题的原因是<context:property-placeholder/>
标签会加载系统的环境变量,而且环境变量的值会被优先加载,如何查看系统的环境变量?
public static void main(String[] args) throws Exception{
Map<String, String> env = System.getenv();
System.out.println(env);
}
大家可以自行运行,在打印出来的结果中会有一个USERNAME=XXX[自己电脑的用户名称],而这个username才是上面配置文件中所对应的。
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"
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">
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
</beans>
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/mybatis
jdbc.username=root
jdbc.password=********
jdbc2.properties
username=root666
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"
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">
<!--方式一 -->
<context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>
<!--方式二-->
<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>
<!--方式三 -->
<context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>
<!--方式四-->
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>
</beans>
说明:
- 方式一:可以实现,如果配置文件多的话,每个都需要配置
- 方式二:
*.properties
代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准 - 方式三:标准的写法,
classpath:
代表的是从根路径下开始查找,但是只能查询当前项目的根路径 - 方式四:不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件