Spring容器之IoC(二)-- 依赖注入

阳光穿透心脏的1/2处 2023-09-25 18:13 132阅读 0赞

format_png

Spring容器之IoC(二)— 依赖注入

DI(Dependency Injection):依赖注入,依赖注入实现了控制反转的思想。指Spring创建对象的过程中,将对象依赖属性通过配置进行注入。 依赖指的是对象和对象之间的关联关系。注入指的是一种数据传递行为,通过注入行为来让对象和对象产生关系。

依赖注入常见的实现方式包括两种:set注入和构造注入

1. 依赖注入之setter注入

①创建学生类Student 该类需要包括无参构造函数,以及每个属性的set方法

  1. publicclassStudent {
  2. privateInteger id;
  3. privateString name;
  4. privateInteger age;
  5. privateString sex;
  6. publicStudent() {
  7. }
  8. publicIntegergetId() {return id;}
  9. publicvoidsetId(Integer id) {this.id = id;}
  10. publicStringgetName() {return name;}
  11. publicvoidsetName(String name) {this.name = name;}
  12. publicIntegergetAge() { return age;}
  13. publicvoidsetAge(Integer age) {this.age = age;}
  14. publicStringgetSex() {return sex;}
  15. publicvoidsetSex(String sex) {this.sex = sex;}
  16. @Override
  17. publicStringtoString() {
  18. return"Student{" +
  19. "id=" + id +
  20. ", name='" + name + ''' +
  21. ", age=" + age +
  22. ", sex='" + sex + ''' +
  23. '}';
  24. }
  25. }
  26. 复制代码

②配置bean时为属性赋值

  1. <beanid="studentOne"class="com.qiuye.spring6.bean.Student">
  2. <!-- property标签:通过组件类的setXxx()方法给组件对象设置属性 -->
  3. <!-- name属性:指定属性名(这个属性名是getXxx()、setXxx()方法定义的,和成员变量无关) -->
  4. <!-- value属性:指定属性值 -->
  5. <propertyname="id"value="1001"></property>
  6. <propertyname="name"value="张三"></property>
  7. <propertyname="age"value="23"></property>
  8. <propertyname="sex"value="男"></property></bean>复制代码

再次强调一下:

  1. 使用set注入必须给该属性提供一个set方法。 Spring容器会调用这个set方法,来给该属性赋值。这个set方法,可以是不使用IDEA工具生成的,也可以不符合javabean规范,但是这个方法必须是以set单词开始的也就是说前三个字母不能随便写,必须是以”set”开头

  2. 若想让Spring调用对应的set方法,需要配置property标签,该标签的主要属性是name和ref,name的属性值是想要注入属性的set方法名去掉“set”,然后把剩下的单词首字母变小写。ref翻译为引用,ref要指定的是要注入bean的id。(后面会讲property标签的value和ref标签的具体用法)

2、依赖注入之构造器注入

①在Student类中添加有参构造

  1. public Student(Integer id, String name, Integer age, String sex) {
  2. this.id = id;
  3. this.name = name;
  4. this.age = age;
  5. this.sex = sex;
  6. }
  7. 复制代码

②配置bean

spring-di.xml

  1. <bean id="studentTwo" class="com.qiuye.spring6.bean.Student">
  2. <constructor-arg name="id" value="1001"/>
  3. <constructor-arg index="1" value="小明"/>
  4. <constructor-arg value="15"/>
  5. <constructor-arg value="男"/>
  6. </bean>
  7. 复制代码

注意:
constructor-arg标签还有两个属性可以进一步描述构造器参数:
index属性:指定参数所在位置的索引(从0开始)
name属性:指定参数名
直接根据类型去匹配

3、Set注入详细使用

3.1、特殊值处理

了解一些特殊值的处理之前先了解一下spring里认为哪些被称为简单值类型,以下是BeanUtils类的方法,该方法的作用是检查给定类型是否表示“简单”值类型:基本数据类型或基本数据类型的包装器、枚举、字符串或其他字符序列、数字、日期、时态、URI、URL、区域设置或类,并且 void 不被视为简单值类型。:

  1. package org.springframework.beans;
  2. publicabstractclassBeanUtils {
  3. ······
  4. /**
  5. * Check if the given type represents a "simple" value type: a primitive or
  6. * primitive wrapper, an enum, a String or other CharSequence, a Number, a
  7. * Date, a Temporal, a URI, a URL, a Locale, or a Class.
  8. * <p>{@code Void} and {@code void} are not considered simple value types.
  9. * @param type the type to check
  10. * @return whether the given type represents a "simple" value type
  11. * @see #isSimpleProperty(Class)
  12. */publicstaticbooleanisSimpleValueType(Class<?> type) {
  13. return (Void.class != type && void.class != type &&
  14. (ClassUtils.isPrimitiveOrWrapper(type) ||
  15. Enum.class.isAssignableFrom(type) ||
  16. CharSequence.class.isAssignableFrom(type) ||
  17. Number.class.isAssignableFrom(type) ||
  18. Date.class.isAssignableFrom(type) ||
  19. Temporal.class.isAssignableFrom(type) ||
  20. URI.class == type ||
  21. URL.class == type ||
  22. Locale.class == type ||
  23. Class.class == type));
  24. }
  25. ······
  26. }
  27. 复制代码

下面再来看一些特殊的值,就是这些特殊的该怎么注入到属性里面

①字面量赋值

什么是字面量?
int a = 10;
声明一个变量a,初始化为10,此时a就不代表字母a了,而是作为一个变量的名字。当我们引用a的时候,我们实际上拿到的值是10。
而如果a是带引号的:’a’,那么它现在不是一个变量,它就是代表a这个字母本身,这就是字面量。所以字面量没有引申含义,就是我们看到的这个数据本身。

  1. <!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 --><propertyname="name"value="张三"/>复制代码
②null值

注入空字符串使用:或者 value=””

注入null使用: 或者 不为该属性赋值

  1. <propertyname="name">
  2. <null /></property>复制代码

注意:

复制代码
以上写法,name属性是有值的,所赋的值就是字符串‘null’

③xml特殊字符

XML中有5个特殊字符,分别是:<、>、’、”、&

以上5个特殊符号在XML中会被特殊对待,会被当做XML语法的一部分进行解析,如果这些特殊符号直接出现在注入的字符串当中,会报错。举个例子:

  1. <!-- 小于号在XML文档中用来定义标签的开始,不能随便使用 --><!-- 解决方案一:使用XML实体符号来代替 --><propertyname="expression"value="a < b"/>复制代码



























特殊字符

转义字符

>

&gt;

<

&lt;

&apos;

&quot;

&

&amp;

除了使用实体符号来代替,也可以使用CDATA节

  1. <propertyname="expression">
  2. <!-- 解决方案二:使用CDATA节 -->
  3. <!-- CDATA中的C代表Character,是文本、字符的含义,CDATA就表示纯文本数据 -->
  4. <!-- XML解析器看到CDATA节就知道这里是纯文本,就不会当作XML标签或属性来解析 -->
  5. <!-- 所以CDATA节中写什么符号都随意,必须将内容写在[]里 -->
  6. <!-- 使用CDATA节必须使用value标签 -->
  7. <value><![CDATA[a < b]]></value></property>复制代码

注意:使用CDATA时,不能使用value属性,只能使用value标签。

④Date

Date虽然被Spring认为是简单值类型,使用value赋值,但是value后的字符串不能随便写,格式必须符合Date的toString()方法格式,例如Thu Mar 02 18:06:45 HKT 2023。但是,Date也可以用ref进行赋值,用ref赋值的方式有很多,主要是看用什么样的方式构造出一个Date类型的对象。

  1. <!-- 示例1--><propertyname="birth"value="Thu Mar 02 18:06:45 HKT 2023"></property><!-- 示例2--><!--用Date类型的构造函数创建一个Date对象,再把它注入到birth属性上--><beanid="Date"class="java.util.Date"><propertyname="time"value="10000"/></bean><propertyname="birth"ref="Date"/>复制代码

3.2、为对象类型属性赋值

①创建班级类Clazz

  1. publicclassClazz {
  2. private Integer clazzId;
  3. privateString clazzName;
  4. public Integer getClazzId(){return clazzId;}
  5. publicvoidsetClazzId(Integer clazzId){this.clazzId = clazzId;}
  6. publicStringgetClazzName(){return clazzName;}
  7. publicvoidsetClazzName(String clazzName){this.clazzName = clazzName;}
  8. @Override
  9. publicStringtoString(){
  10. return"Clazz{" +
  11. "clazzId=" + clazzId +
  12. ", clazzName='" + clazzName + ''' +
  13. '}';
  14. }
  15. publicClazz(){}
  16. publicClazz(Integer clazzId, String clazzName){
  17. this.clazzId = clazzId;
  18. this.clazzName = clazzName;
  19. }
  20. }
  21. 复制代码

②修改Student类

在Student类中添加以下代码:

  1. privateClazz clazz;
  2. publicClazzgetClazz() {
  3. return clazz;
  4. }
  5. publicvoidsetClazz(Clazz clazz) {
  6. this.clazz = clazz;
  7. }
  8. 复制代码
3.2.1、引用外部bean

配置Clazz类型的bean:

  1. <bean id="clazzOne" class="com.qiuye.spring6.bean.Clazz">
  2. <property name="clazzId" value="1111"></property>
  3. <property name="clazzName" value="1班"></property>
  4. </bean>
  5. 复制代码

为Student中的clazz属性赋值:

  1. <beanid="studentFour"class="com.qiuye.spring6.bean.Student">
  2. <propertyname="id"value="1004"></property>
  3. <propertyname="name"value="赵六"></property>
  4. <propertyname="age"value="26"></property>
  5. <propertyname="sex"value="女"></property>
  6. <!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
  7. <propertyname="clazz"ref="clazzOne"></property></bean>复制代码

错误演示:

  1. <bean id="studentFour" class="com.qiuye.spring6.bean.Student">
  2. <property name="id" value="1004"></property>
  3. <property name="name" value="赵六"></property>
  4. <property name="age" value="26"></property>
  5. <property name="sex" value="女"></property>
  6. <property name="clazz" value="clazzOne"></property>
  7. </bean>
  8. 复制代码

如果错把ref属性写成了value属性,会抛出异常: Caused by: java.lang.IllegalStateException: Cannot convert value of type ‘java.lang.String’ to required type ‘com.qiuye.spring6.bean.Clazz’ for property ‘clazz’: no matching editors or conversion strategy found
意思是不能把String类型转换成我们要的Clazz类型,说明我们使用value属性时,Spring只把这个属性看做一个普通的字符串,不会认为这是一个bean的id,更不会根据它去找到bean来赋值

3.2.2、内部bean
  1. <beanid="studentFour"class="com.qiuye.spring6.bean.Student">
  2. <propertyname="id"value="1004"></property>
  3. <propertyname="name"value="赵六"></property>
  4. <propertyname="age"value="26"></property>
  5. <propertyname="sex"value="女"></property>
  6. <propertyname="clazz">
  7. <!-- 在一个bean中再声明一个bean就是内部bean -->
  8. <!-- 内部bean只能用于给属性赋值,不能在外部通过IOC容器获取,因此可以省略id属性 -->
  9. <beanid="clazzInner"class="com.qiuye.spring6.bean.Clazz">
  10. <propertyname="clazzId"value="2222"></property>
  11. <propertyname="clazzName"value="2班"></property>
  12. </bean>
  13. </property></bean>复制代码
3.2.3、级联属性赋值

使用级联属性赋值,被注入的类的该属性必须提供get方法,例如把Clazz对象注入到Student对象,Student类必须提供clazz属性的get方法,而且再Bean标签里面必须先给clazz赋值,再给clazz下的属性赋值,顺序不能颠倒。

  1. <bean id="studentFour" class="com.qiuye.spring6.bean.Student">
  2. <property name="id" value="1004"></property>
  3. <property name="name" value="赵六"></property>
  4. <property name="age" value="26"></property>
  5. <property name="sex" value="女"></property>
  6. <property name="clazz" ref="clazzOne"></property>
  7. <property name="clazz.clazzId" value="3333"></property>
  8. <property name="clazz.clazzName" value="3班"></property>
  9. </bean>
  10. 复制代码
3.2.4、为数组类型属性赋值

①修改Student类

在Student类中添加hobbies属性,类型是数组:

  1. privateString[] hobbies;
  2. publicString[] getHobbies() {
  3. return hobbies;
  4. }
  5. publicvoidsetHobbies(String[] hobbies) {
  6. this.hobbies = hobbies;
  7. }
  8. 复制代码

②配置bean

  1. <beanid="studentFour"class="com.qiuye.spring.bean6.Student">
  2. <propertyname="id"value="1004"></property>
  3. <propertyname="name"value="赵六"></property>
  4. <propertyname="age"value="26"></property>
  5. <propertyname="sex"value="女"></property>
  6. <!-- ref属性:引用IOC容器中某个bean的id,将所对应的bean为属性赋值 -->
  7. <propertyname="clazz"ref="clazzOne"></property>
  8. <!--当数组里放的是简单类型,使用value标签 -->
  9. <propertyname="hobbies">
  10. <array>
  11. <value>抽烟</value>
  12. <value>喝酒</value>
  13. <value>烫头</value>
  14. </array>
  15. </property>
  16. <!--当数组里放的是其他引用类型,使用ref标签 -->
  17. <propertyname="as">
  18. <array>
  19. <refbean="a1"></ref>
  20. <refbean="a2"></ref><refbean="a3"></ref><refbean="a4"></ref>
  21. </array>
  22. </property></bean>a
  23. <beanid="a1"class="com.qiuye.spring.bean6.a"></bean><beanid="a2"class="com.qiuye.spring.bean6.a"></bean><beanid="a3"class="com.qiuye.spring.bean6.a"></bean><beanid="a4"class="com.qiuye.spring.bean6.a"></bean>复制代码
3.2.5、为集合类型属性赋值
①为List集合类型属性赋值

在Clazz类中添加以下代码:

  1. privateList<Student> students;
  2. publicList<Student> getStudents() {
  3. return students;
  4. }
  5. publicvoidsetStudents(List<Student> students) {
  6. this.students = students;
  7. }
  8. 复制代码

配置bean:

  1. <beanid="clazzTwo"class="com.qiuye.spring6.bean.Clazz">
  2. <propertyname="clazzId"value="4444"></property>
  3. <propertyname="clazzName"value="Javaee0222"></property>
  4. <propertyname="students">
  5. <list>
  6. <refbean="studentOne"></ref>
  7. <refbean="studentTwo"></ref>
  8. <refbean="studentThree"></ref>
  9. </list>
  10. </property></bean>复制代码

若为Set集合类型属性赋值,只需要将其中的list标签改为set标签即可,同数组一样注入简单类型用value标签,注入其他类型用ref标签。

②为Map集合类型属性赋值

创建教师类Teacher:

  1. publicclassTeacher {
  2. privateInteger teacherId;
  3. privateString teacherName;
  4. publicIntegergetTeacherId() {
  5. return teacherId;
  6. }
  7. publicvoidsetTeacherId(Integer teacherId) {
  8. this.teacherId = teacherId;
  9. }
  10. publicStringgetTeacherName() {
  11. return teacherName;
  12. }
  13. publicvoidsetTeacherName(String teacherName) {
  14. this.teacherName = teacherName;
  15. }
  16. publicTeacher(Integer teacherId, String teacherName) {
  17. this.teacherId = teacherId;
  18. this.teacherName = teacherName;
  19. }
  20. publicTeacher() {
  21. }
  22. @Override
  23. publicStringtoString() {
  24. return"Teacher{" +
  25. "teacherId=" + teacherId +
  26. ", teacherName='" + teacherName + ''' +
  27. '}';
  28. }
  29. }
  30. 复制代码

在Student类中添加以下代码:

  1. privateMap<String, Teacher> teacherMap;
  2. publicMap<String, Teacher> getTeacherMap() {
  3. return teacherMap;
  4. }
  5. publicvoidsetTeacherMap(Map<String, Teacher> teacherMap) {
  6. this.teacherMap = teacherMap;
  7. }
  8. 复制代码

配置bean:

  1. <beanid="teacherOne"class="com.qiuye.spring6.bean.Teacher">
  2. <propertyname="teacherId"value="1001"></property>
  3. <propertyname="teacherName"value="数学老师"></property></bean>
  4. <beanid="teacherTwo"class="com.qiuye.spring6.bean.Teacher">
  5. <propertyname="teacherId"value="1002"></property>
  6. <propertyname="teacherName"value="语文老师"></property></bean>
  7. <beanid="studentFour"class="com.qiuye.spring6.bean.Student">
  8. <propertyname="id"value="1004"></property>
  9. <propertyname="name"value="赵六"></property>
  10. <propertyname="age"value="26"></property>
  11. <propertyname="sex"value="女"></property>
  12. <propertyname="clazz"ref="clazzOne"></property>
  13. <propertyname="hobbies">
  14. <array>
  15. <value>抽烟</value>
  16. <value>喝酒</value>
  17. <value>烫头</value>
  18. </array>
  19. </property>
  20. <propertyname="teacherMap">
  21. <map>
  22. <entry>
  23. <key>
  24. <value>10010</value>
  25. </key>
  26. <refbean="teacherOne"></ref>
  27. </entry>
  28. <entry>
  29. <key>
  30. <value>10086</value>
  31. </key>
  32. <refbean="teacherTwo"></ref>
  33. </entry>
  34. </map>
  35. </property></bean>复制代码

要点:

  • 使用标签

  • 如果key是简单类型,使用 key 属性,反之使用 key-ref 属性。

  • 如果value是简单类型,使用 value 属性,反之使用 value-ref 属性。

③注入Properties

java.util.Properties继承java.util.Hashtable,所以Properties也是一个Map集合。它的key和value都是String类型,使用标签嵌套标签完成。

  1. <beanid="peopleBean"class="com.qiuye.spring6.beans.People"><propertyname="properties"><props><propkey="driver">com.mysql.cj.jdbc.Driver</prop><propkey="url">jdbc:mysql://localhost:3306/spring</prop><propkey="username">root</prop><propkey="password">123456</prop></props></property></bean>复制代码
3.2.6、p命名空间

引入p命名空间 xmlns:p=”www.springframework.org/schema/p“

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:util="http://www.springframework.org/schema/util"
  5. xmlns:p="http://www.springframework.org/schema/p"
  6. xsi:schemaLocation="http://www.springframework.org/schema/util
  7. http://www.springframework.org/schema/util/spring-util.xsd
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans.xsd">
  10. 复制代码

引入p命名空间后,可以通过以下方式为bean的各个属性赋值,非简单类型需要加ref

  1. <bean id="studentSix" class="com.qiuye.spring6.bean.Student"
  2. p:id="1006" p:name="小明" p:clazz-ref="clazzOne" p:teacherMap-ref="teacherMap"></bean>
  3. 复制代码

p命名空间是简化set注入的,所以它基于set方法注入的

3.2.7、C命名空间

C命名空间是为了简化构造注入的配置,使用c命名空间需要引入xmlns:c=”www.springframework.org/schema/c“,并且需要提供构造方法

  1. <bean id="People" class="com.qiuye.spring6_03.entity.People"
  2. c:name="小米" c:_0="1" c:isMan="true">
  3. </bean>
  4. 复制代码
3.2.8、util命名空间

Util命名空间的作用是允许配置复用,就是一些相同属性可以提取出来,在需用的地方进行引入。 在使用util命名空间之前,需要先引入xmlns:util=”http://www.springframework.org/schema/util”和http://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util.xsd 需要注意引入的内容和地方。

util命名空间主要是针对集合来使用的,具体就需要看场景需求。

format_png 1

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:util="http://www.springframework.org/schema/util"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
  7. <util:properties id="datasource">
  8. <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
  9. <prop key="url">jdbc:mysql://localhost:3306/spring</prop>
  10. <prop key="username">root</prop>
  11. <prop key="password">123456</prop>
  12. </util:properties>
  13. <bean id="datasource1" class="com.qiuye.spring6_03.dao.DataSource1">
  14. <property name="properties" ref="datasource"/>
  15. </bean>
  16. <bean id="datasource2" class="com.qiuye.spring6_03.dao.DataSource2">
  17. <property name="properties" ref="datasource"/>
  18. </bean>
  19. </beans>
  20. 复制代码
3.2.9、自动装配

Spring还可以完成自动化的注入,自动化注入又被称为自动装配。它可以根据名字进行自动装配,也可以根据类型进行自动装配。

  1. publicclassUserService {
  2. private UserDAO userDAO;
  3. private UserMysqlDAO userMysqlDAO;
  4. publicvoidsetDao(UserDAO userDAO) {
  5. this.userDAO = userDAO;
  6. }
  7. publicvoidsetUserMysqlDAO(UserMysqlDAO userMysqlDAO) {
  8. this.userMysqlDAO = userMysqlDAO;
  9. }
  10. publicvoidadd(){
  11. userDAO.add();
  12. userMysqlDAO.add();
  13. }
  14. }
  15. 复制代码
  16. <bean id="dao" class="com.qiuye.spring6_03.dao.UserDAO"/>
  17. <bean id="userMysqlDAO" class="com.qiuye.spring6_03.dao.UserMysqlDAO"/>
  18. <bean id="dao1" class="com.qiuye.spring6_03.dao.UserMysqlDAO"></bean>
  19. <bean id="userService" class="com.qiuye.spring6_03.service.UserService" autowire="byName"/>
  20. 复制代码

这个配置起到关键作用:

  • UserService Bean中需要添加autowire=”byName”,表示通过名称进行装配。

  • UserService类中有一个UserDao属性,而UserDao属性的名字是dao,对应的set方法是setDao() ,正好和UserDao Bean的id是一样的。这就是根据名称自动装配。

  • 所以根据名称进行自动装配需要注意的是:提供set方法和bean标签id属性的值

再来看看根据类型进行自动装配,此时需要使用autowire=”byType”:

  1. <bean class="com.qiuye.spring6_03.dao.UserDAO"/>
  2. <bean class="com.qiuye.spring6_03.dao.UserMysqlDAO"/>
  3. <bean id="userService" class="com.qiuye.spring6_03.service.UserService" autowire="byType"/>
  4. 复制代码

同理,byType在装配的时候都是基于set方法的。所以set方法是必须要提供的。提供构造方法是不行的,大家可以测试一下。有一点需要注意,根据类型装配时,如果配置文件中有两个类型一样的bean,会抛出异常,所以使用byType时,必须保证注入的bean类型是唯一的。

3.2.10、引入外部属性配置文件

我们都知道编写数据源的时候是需要连接数据库的信息的,例如:driver url username password等信息。如果把这些信息单独写到一个属性配置文件中,这样用户修改起来不就会更加的方便嘛。

①在类路径下新建jdbc.properties文件

  1. driver=com.mysql.cj.jdbc.Driver
  2. url=jdbc:mysql://localhost:3306/spring
  3. username=root
  4. password=root123
  5. 复制代码

②在spring中配置文件里面引入context命名空间

xmlns:context=”http://www.springframework.org/schema/context”和http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd

③使用context命名空间的标签,使用location来指定文件的位置,用${}来获取对应key的值

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  7. <context:property-placeholder location="jdbc.properties"/>
  8. <bean id="dataSource" class="com.powernode.spring6.beans.MyDataSource">
  9. <property name="driver" value="${driver}"/>
  10. <property name="url" value="${url}"/>
  11. <property name="username" value="${username}"/>
  12. <property name="password" value="${password}"/>
  13. </bean>
  14. </beans>

发表评论

表情:
评论列表 (有 0 条评论,132人围观)

还没有评论,来说两句吧...

相关阅读