前面我们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
说明:
然后我们验证一下是否配置成功:
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进行依赖注入!
注意:
类没有发现的异常
,具体的类为com.mysql.jdbc.Driver
。错误的原因是缺少mysql的驱动包。我们在项目的pom文件中添加驱动坐标即可。刚才我们完成了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
命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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配置文件中的内容并完成属性注入
<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.出现问题的原因是
标签会加载系统的环境变量,而且环境变量的值会被优先加载,如何查看系统的环境变量?
public static void main(String[] args) throws Exception{
Map<String, String> env = System.getenv();
System.out.println(env);
}
大家可以自行运行,在打印出来的结果中会有一个USERNAME=XXX[自己电脑的用户名称],而这个username才是上面配置文件中所对应的。
5.解决方案
<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
<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:
代表的是从根路径下开始查找,但是只能查询当前项目的根路径