1.IoC 控制反转
- 控制反转是一种思想。
- 控制反转是为了降低程序耦合度,提高程序扩展力,达到OCP原则,达到DIP原则。
- 控制反转,反转的是什么?
- 将对象的创建权利交出去,交给第三方容器负责。
- 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
- 控制反转这种思想如何实现呢?
- DI(Dependency Injection):依赖注入
2.依赖注入
依赖注入实现了控制反转的思想。
Spring通过依赖注入的方式来完成Bean管理的。
Bean管理说的是:Bean对象的创建,以及Bean对象中属性的赋值(或者叫做Bean对象之间关系的维护)。
依赖注入:
- 依赖指的是对象和对象之间的关联关系。
- 注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。
依赖注入常见的实现方式包括两种:
- 第一种:set注入
- 第二种:构造注入
set注入和构造注入的时机是不同的。set注入是调用set方法,此时对象早已创建出来了。而构造注入调用的是构造方法,是在对象创建的时刻进行注入。
2.1 set注入
set注入,基于set方法实现的,底层会通过反射机制调用属性对应的set方法然后给属性赋值。这种方式要求属性必须对外提供set方法。
通过UserService调用UserDao里面的方法
package com.powernode.spring6.dao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* bean
*/
public class UserDao {
// 记录日志
private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
public void insert(){
logger.info("数据库正在保存用户信息");
}
}
package com.powernode.spring6.service;
import com.powernode.spring6.dao.UserDao;
/**
* bean
*/
public class UserService {
private UserDao userDao;
// set注入,必须要提供一个set方法
// Spring容器会调用这个set方法,来给userDao属性赋值
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void savaUser(){
// 调用userDao的insert()方法
userDao.insert();
}
}
spring配置文件中配置
<?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">
<!--配置dao-->
<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
<!--配置service-->
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<!--Spring调用对应的set方法,需要配置property标签-->
<!--name属性指定值:set方法的方法名去掉set,剩下的单词首字母小写-->
<!--ref:引用,ref后面指定的是要注入的bean的id-->
<property name="userDao" ref="userDaoBean"/>
</bean>
</beans>
测试程序
package com.powernode.spring6.test;
import com.powernode.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDITest {
@Test
public void testSetDI(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = applicationContext.getBean("userServiceBean", UserService.class);
userService.savaUser();
}
}
实现原理:
通过property标签获取到属性名:userDao
通过属性名推断出set方法名:setUserDao
通过反射机制调用setUserDao()方法给属性赋值
property标签的name是属性名,set方法的方法名去掉set,剩下的单词首字母小写。
property标签的ref是要注入的bean对象的id。(通过ref属性来完成bean的装配,这是bean最简单的一种装配方式。装配指的是:创建系统组件之间关联的动作)
总结:set注入的核心实现原理:通过反射机制调用set方法来给属性赋值,让两个对象之间产生关系。
2.2 构造注入
核心原理:通过调用构造方法来给属性赋值。
package com.powernode.spring6.service;
import com.powernode.spring6.dao.UserDao;
/**
* bean
*/
public class UserService {
private UserDao userDao;
// 通过反射机制调用构造方法给属性赋值
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public void savaUser(){
// 调用userDao的insert()方法
userDao.insert();
}
}
spring配置文件中配置
<?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">
<!--配置dao-->
<bean id="userDaoBean" class="com.powernode.spring6.dao.UserDao"/>
<!--配置service-->
<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
<!--构造注入-->
<!--
index属性指定参数下标,第一个参数是0,第二个参数是1,...
ref属性用来指定要注入的bean的id
-->
<!--指定构造方法的第一个参数,下标是0-->
<constructor-arg index="0" ref="userDaoBean"/>
</bean>
<bean id="userServiceBean2" class="com.powernode.spring6.service.UserService">
<!--根据参数构造方法的名字注入-->
<constructor-arg name="userDao" ref="userDaoBean"/>
</bean>
<bean id="userServiceBean3" class="com.powernode.spring6.service.UserService">
<!--不指定下标,也不指定参数名,spring自己做类型匹配-->
<!--这种方法实际上是根据类型进行注入的,spring会自动根据类型来判断把ref注入给哪个参数-->
<constructor-arg ref="userDaoBean"/>
</bean>
</beans>
通过构造方法注入的时候:
- 可以通过下标
- 可以通过参数名
- 也可以不指定下标和参数名,可以类型自动推断。
3 set注入专题
3.1 注入外部Bean
<!--声明Bean-->
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"/>
<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService">
<!--使用ref引入,注入外部Bean-->
<property name="orderDao" ref="orderDaoBean"/>
</bean>
外部Bean的特点:bean定义到外面,在property标签中使用ref属性进行注入。通常这种方式是常用。
3.2 注入内部Bean
内部Bean的方式:在bean标签中嵌套bean标签。
<bean id="orderServiceBean2" class="com.powernode.spring6.service.OrderService">
<property name="orderDao">
<!--property标签使用嵌套的bean标签,内部bean-->
<bean class="com.powernode.spring6.dao.OrderDao"/>
</property>
</bean>
这种方式很少用
3.3 注入简单类型
一个普通的java类
package com.powernode.spring6.bean;
public class User {
private String username;
private String password;
private int age;
// 省略set,toString方法
}
<!--注入简单类型-->
<bean id="userBean" class="com.powernode.spring6.bean.User">
<!--给简单类型赋值,不能使用ref,需要使用value-->
<property name="username" value="张三"/>
<property name="password" value="123"/>
<property name="age" value="20"/>
</bean>
需要特别注意:如果给简单类型赋值,使用value属性或value标签。而不是ref。
Spring的BeanUtils类源码
public static boolean isSimpleProperty(Class<?> type) {
Assert.notNull(type, "'type' must not be null");
return isSimpleValueType(type) || type.isArray() && isSimpleValueType(type.getComponentType());
}
public static boolean isSimpleValueType(Class<?> type) {
return (Void.class != type && void.class != type &&
(ClassUtils.isPrimitiveOrWrapper(type) ||
Enum.class.isAssignableFrom(type) ||
CharSequence.class.isAssignableFrom(type) ||
Number.class.isAssignableFrom(type) ||
Date.class.isAssignableFrom(type) ||
Temporal.class.isAssignableFrom(type) ||
URI.class == type ||
URL.class == type ||
Locale.class == type ||
Class.class == type));
}
通过源码分析得知,简单类型包括:
- 基本数据类型
- 基本数据类型对应的包装类
- String或其他的CharSequence子类
- Number子类
- Date子类
- Enum子类
- URI
- URL
- Temporal子类
- Locale
- Class
- 另外还包括以上简单值类型对应的数组类型。
需要注意的是:
- 如果把Date当做简单类型的话,日期字符串格式不能随便写。格式必须符合Date的toString()方法格式Thu Mar 02 18:06:45 HKT 2023。显然这就比较鸡肋了。如果我们提供一个这样的日期字符串:2010-10-11,在这里是无法赋值给Date类型的属性的。一般不会把Date当作简单类型,虽然它是简单类型,一般会采用ref给Date类型的属性赋值
- spring6之后,当注入的是URL,那么这个url字符串是会进行有效性检测的。如果是一个存在的url,那就没问题。如果不存在则报错。
经典案例:给数据源的属性注入值:
假设我们现在要自己手写一个数据源,所有的数据源都要实现javax.sql.DataSource接口,并且数据源中应该有连接数据库的信息,例如:driver、url、username、password等。
package com.powernode.spring6.jdbc;
/**
* 所有的数据源都要实现java规范:javax.sql.DataSource
* 什么是数据源:能够提供Connection对象的,都是数据源
*/
public class MyDataSource implements DataSource {
// 把数据源交给Spring容器来管理
private String driver;
private String url;
private String username;
private String password;
@Override
public Connection getConnection() throws SQLException {
// 获取数据库连接对象的时候需要4个信息:driver url username password
return null;
}
// 省略接口的其他方法
// 省略driver url username password的set方法
}
<?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">
<!--Spring管理数据源-->
<bean id="myDataSource" class="com.powernode.spring6.jdbc.MyDataSource">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
</beans>
测试
package com.powernode.spring6.test;
public class SpringSetDITest {
@Test
public void testMyDataSource(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
MyDataSource myDataSource = applicationContext.getBean("myDataSource", MyDataSource.class);
System.out.println(myDataSource);
}
}
输出
MyDataSource{driver='com.mysql.cj.jdbc.Driver', url='jdbc:mysql://localhost:3306/spring6', username='root', password='root'}
3.4 级联属性赋值(了解)
<bean id="clazzBean" class="com.powernode.spring6.beans.Clazz"/>
<bean id="student" class="com.powernode.spring6.beans.Student">
<property name="name" value="张三"/>
<!--要点1:以下两行配置的顺序不能颠倒-->
<property name="clazz" ref="clazzBean"/>
<!--要点2:clazz属性必须还要有getter方法-->
<property name="clazz.name" value="高三一班"/>
</bean>
</beans>
3.5 注入数组
当数组中的元素是简单类型:
private String[] username;
<bean id="user" class="com.powernode.spring6.beans.User">
<!--数组属性中的元素类型是String简单类型-->
<property name="username">
<array>
<value>张三</value>
<value>李四</value>
<value>王五</value>
</array>
</property>
</bean>
当数组中的元素是非简单类型:
<bean id="goods1" class="com.powernode.spring6.beans.Goods">
<property name="name" value="西瓜"/>
</bean>
<bean id="goods2" class="com.powernode.spring6.beans.Goods">
<property name="name" value="苹果"/>
</bean>
<bean id="order" class="com.powernode.spring6.beans.Order">
<property name="goods">
<array>
<!--这里使用ref标签即可-->
<ref bean="goods1"/>
<ref bean="goods2"/>
</array>
</property>
</bean>
要点:
- 如果数组中是简单类型,使用value标签。
- 如果数组中是非简单类型,使用ref标签
3.6 注入List集合和Set集合
List集合:有序可重复
Set集合:无序不可重复
<bean id="personBean" class="com.powernode.spring6.bean.Person">
<property name="names">
<list>
<value>张三</value>
<value>李四</value>
<value>李四</value>
</list>
</property>
<property name="adds">
<set>
<value>北京</value>
<value>深圳</value>
</set>
</property>
</bean>
注入List集合的时候使用list标签,如果List集合中是简单类型使用value标签,反之使用ref标签。
注入Set集合的时候使用set标签 , 如果Set集合中是简单类型使用value标签,反之使用ref标签
3.7 注入Map集合
<bean id="personBean" class="com.powernode.spring6.bean.Person">
<property name="phones">
<!--注入Map集合-->
<map>
<!--如果key和value是简单类型用key,value-->
<entry key="1" value="110"/>
<entry key="2" value="120"/>
<!--如果key和value不是简单类型用key-ref,value-ref-->
<!--<entry key-ref="" value-ref=""/>-->
</map>
</property>
</bean>
使用<map>标签
如果key是简单类型,使用 key 属性,反之使用 key-ref 属性。
如果value是简单类型,使用 value 属性,反之使用 value-ref 属性
3.8 注入Properties
Properties本质上也是一个Map集合
java.util.Properties继承java.util.Hashtable,Hashtable实现了Map接口
虽然Properties也是一个Map集合,和Map的注入方式有点像,但是不同
Properties的key和value只能是String类型
<bean id="personBean" class="com.powernode.spring6.bean.Person">
<!--注入Properties属性类对象-->
<property name="properties">
<props>
<prop key="driver">com.mysql.cj.jdbc.Driver</prop>
<prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
</bean>
使用<props>标签嵌套<prop>标签完成。
3.9 注入null和空字符串
<!--注入null和空字符串-->
<bean id="userBean2" class="com.powernode.spring6.bean.User">
<!--不给属性注入,默认值就是null-->
<!--<property name="username" value="张三"/>-->
<!--这不是注入null,只是注入了"null"字符串-->
<!--<property name="username" value="null"/>-->
<!--手动注入null-->
<!--<property name="username">
<null/>
</property>-->
<!--注入空字符串-->
<!--<property name="username" value=""/>-->
<!--注入空字符串-->
<property name="username">
<value/>
</property>
<property name="password" value="123"/>
<property name="age" value="20"/>
</bean>
注入空字符串使用:<value/> 或者 value=“”
注入null使用:<null/> 或者 不为该属性赋值
3.10 注入的值中含有特殊符号
XML中有5个特殊字符,分别是:<、>、'、"、&
以上5个特殊符号在XML中会被特殊对待,会被当做XML语法的一部分进行解析,如果这些特殊符号直接出现在注入的字符串当中,会报错。
解决方案包括两种:
第一种:特殊符号使用转义字符代替。
第二种:将含有特殊符号的字符串放到:<![CDATA[]]> 当中。因为放在CDATA区中的数据不会被XML文件解析器解析。
5个特殊字符对应的转义字符分别是:
特殊字符 | 转义字符 |
---|---|
> | > |
< | < |
’ | ' |
" | " |
& | & |
<bean id="mathBean" class="com.powernode.spring6.bean.MathBean">
<!--第一种方案:使用实体符号代替特殊符号-->
<!--<property name="result" value="2 < 3"/>-->
<!--第二种方案:使用<![CDATA[]]>-->
<property name="result">
<!--只能使用value标签-->
<value><![CDATA[2 < 3]]></value>
</property>
</bean>
使用CDATA时,不能使用value属性,只能使用value标签。
4 p命名空间注入
目的:简化配置。
使用p命名空间注入的前提条件包括两个:
第一:在XML头部信息中添加p命名空间的配置信息:xmlns:p=“http://www.springframework.org/schema/p”
第二:p命名空间注入是基于setter方法的,所以需要对应的属性提供setter方法。
package com.powernode.spring6.bean;
import java.util.Date;
public class Dog {
// 简单类型
private String name;
private int age;
// 非简单类型,虽然Date是简单类型,当作非简单类型看待
private Date birth;
// 省略set、toString方法
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--在spring的配置文件头部添加p命名空间 xmlns:p="http://www.springframework.org/schema/p"-->
<!--使用 p:属性名 = "属性值"-->
<bean id="dogBean" class="com.powernode.spring6.bean.Dog" p:name="张三" p:age="3" p:birth-ref="birthBean"/>
<!--获取系统当前时间-->
<bean id="birthBean" class="java.util.Date"/>
</beans>
测试
@Test
public void testP(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-p.xml");
Dog dogBean = applicationContext.getBean("dogBean", Dog.class);
System.out.println(dogBean);
}
p命名空间实际上是对set注入的简化。
5.c命名空间注入
c命名空间是简化构造方法注入的。
使用c命名空间的两个前提条件:
第一:需要在xml配置文件头部添加信息:xmlns:c=“http://www.springframework.org/schema/c”
第二:需要提供构造方法。
Dog类添加构造方式
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--在spring的配置文件头部添加c命名空间 xmlns:c="http://www.springframework.org/schema/c"-->
<!--使用 下标方式 c:_0 = "属性值"-->
<!--使用 参数名方式 c:name = "属性值"-->
<bean id="dogBean" class="com.powernode.spring6.bean.Dog" c:name="张三" c:age="3" c:birth-ref="birthBean"/>
<!--获取系统当前时间-->
<bean id="birthBean" class="java.util.Date"/>
</beans>
c命名空间是依靠构造方法的。
不管是p命名空间还是c命名空间,注入的时候都可以注入简单类型以及非简单类型。
6 util命名空间
使用util命名空间可以让配置复用。
使用util命名空间的前提是:在spring配置文件头部添加配置信息。
xmlns:util=“http://www.springframework.org/schema/util”
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
假设有两个自己定义的数据源MyDataSource1和MyDataSource2
package com.powernode.spring6.jdbc;
public class MyDataSource1 implements DataSource {
// 把数据源交给Spring容器来管理
// Properties属性类对象,这是一个Map集合,key和value都是String类型
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
// 省略接口方法和toString方法
package com.powernode.spring6.jdbc;
public class MyDataSource2 implements DataSource {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
// 省略接口方法和toString方法
<?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:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!--引入util命名空间
在spring的配置文件头部添加
xmlns:util="http://www.springframework.org/schema/util"
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
-->
<util:properties id="prop">
<prop key="driver">com.mysql.cj.jdbc.Driver</prop>
<prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
<prop key="username">root</prop>
<prop key="password">root</prop>
</util:properties>
<!--数据源1-->
<bean id="myDataSource1" class="com.powernode.spring6.jdbc.MyDataSource1">
<property name="properties" ref="prop"/>
</bean>
<!--数据源2-->
<bean id="myDataSource2" class="com.powernode.spring6.jdbc.MyDataSource2">
<property name="properties" ref="prop"/>
</bean>
</beans>
测试
@Test
public void testUtil(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-util.xml");
MyDataSource1 myDataSource1 = applicationContext.getBean("myDataSource1", MyDataSource1.class);
MyDataSource2 myDataSource2 = applicationContext.getBean("myDataSource2", MyDataSource2.class);
System.out.println(myDataSource1);
System.out.println(myDataSource2);
}
输出
MyDataSource1{properties={password=root, driver=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://localhost:3306/spring6, username=root}}
MyDataSource2{properties={password=root, driver=com.mysql.cj.jdbc.Driver, url=jdbc:mysql://localhost:3306/spring6, username=root}}
7 基于XML的自动装配
Spring还可以完成自动化的注入,自动化注入又被称为自动装配。它可以根据名字进行自动装配,也可以根据类型进行自动装配。
7.1 根据名称自动装配
package com.powernode.spring6.dao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderDao {
private static final Logger logger = LoggerFactory.getLogger(OrderDao.class);
public void insert(){
logger.info("订单正在生成...");
}
}
package com.powernode.spring6.service;
import com.powernode.spring6.dao.OrderDao;
public class OrderService {
private OrderDao orderDao;
// 通过set方法给属性赋值
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
/**
* 生成订单的业务方法
*/
public void generate(){
orderDao.insert();
}
}
<?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">
<!--根据名字进行自动装配-->
<!--自动装配也是基于set方法实现的-->
<bean id="orderService" class="com.powernode.spring6.service.OrderService" autowire="byName"/>
<!--id也叫做bean的名称-->
<!--根据名字进行自动装配的时候,被注入的对象的bean的id不能随便写,set方法的方法名去掉set,剩下单词首字母小写-->
<bean id="orderDao" class="com.powernode.spring6.dao.OrderDao"/>
</beans>
如果根据名称装配(byName),底层会调用set方法进行注入。
例如:setOrderDao() 对应的名字是orderDao,setPassword()对应的名字是password
7.2 根据类型自动装配
<!--根据类型进行自动装配-->
<!--自动装配是基于set方法实现的-->
<bean id="orderService" class="com.powernode.spring6.service.OrderService" autowire="byType"/>
<!--根据类型进行自动装配的时候,在有效得到配置文件中,某种类型的实例只能有一个-->
<bean class="com.powernode.spring6.dao.OrderDao"/>
无论是byName还是byType,在装配的时候都是基于set方法的。所以set方法是必须要提供的。提供构造方法是不行的
8 Spring引入外部属性配置文件
在类路径下新建jdbc.properties文件,并配置信息。
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring6
jdbc.username=root
jdbc.password=root
写一个数据源类,提供相关属性。
package com.powernode.spring6.jdbc;
public class MyDataSource implements DataSource {
// 把数据源交给Spring容器来管理
private String driver;
private String url;
private String username;
private String password;
// 省略set、toString方法和接口方法
在spring配置文件中引入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: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>
<!--引入外部properties文件
引入context命名空间
使用context:property-placeholder标签的location属性来指定属性配置文件的路径
location默认从类的根路径下开始加载资源
-->
<context:property-placeholder location="jdbc.properties"/>
<!--配置数据源-->
<bean id="myDataSource" class="com.powernode.spring6.jdbc.MyDataSource">
<!--取值:使用${key}-->
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
测试程序
@Test
public void testProperties(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-properties.xml");
MyDataSource myDataSource = applicationContext.getBean("myDataSource", MyDataSource.class);
System.out.println(myDataSource);
}
输出
MyDataSource{driver='com.mysql.cj.jdbc.Driver', url='jdbc:mysql://localhost:3306/spring6', username='root', password='root'}