IOC容器
简介
IoC(Inversion of Control)
控制反转,是一种基于面向对象编程法则的设计思想,它设计出的程序具有松耦合、更优良的特点。
IoC容器
是Spring框架中重要的核心组件之一,贯穿了Spring从出生到成长的整个过程,Spring通过IoC
容器管理所有Java对象的实例化和初始化,控制对象与对象之间的实例化、初始化以及依赖关系。由IoC
容器管理的Java对象称为Spring Bean,它与使用new 关键字创建的Java对象没有任何区别。
Bean管理
:Bean对象的创建和Bean对象中属性的的赋值(或者叫Bean对象之间关系的维护)
控制反转,反转的是什么?
- 将对象的创建权交出去,交给第三方容器负责。
- 将对象和对象之间关系的维护权交出去,交给第三方容器负责。
如何实现控制反转?
DI(Dependency Injection)
依赖注入
依赖注入
:指Spring创建对象的过程中,将对象依赖属性通过配置进行注入,它实现了控制反转的思想。当一个对象作为另一个对象的属性的时候,我们可以使用依赖注入的方式将对象的内容注入。
依赖注入的实现方式
:①set注入、②构造注入
IoC在Spring中的实现
Spring的IoC容器中管理的组件叫做Bean, 在创建Bean之前,首先需要创建IoC容器,Spring提供的IoC容器有两种实现方式。
1、BeanFactory
这是IoC容器的基本实现,是Spring内部使用的接口
2、ApplicationContext
BeanFactory
的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有的场合都使用ApplicationContext
而不是底层的BeanFactory
ApplicationContext
的主要实现类
类名 | 简介 |
---|---|
ClassPathXmlApplicationContext | 通过类读取路径下的XML格式的配置文件创建IoC对象 |
FileSystemXmlApplicationContext | 通过文件系统路径读取XML格式的配置文件创建IoC对象 |
ConfigurableApplicationContext | ApplicationContext的子接口,包含一些扩展方法refresh()和close(),让ApplicationContext具有启动、关闭和刷新上下文功能 |
WebApplicationContex | 专门为Web应用准备,基于Web环境创建的IoC容器对象,并将对象引入存入ServletContext域中 |
基于xml管理Bean
步骤
①导入相关依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.9</version>
</dependency>
<dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.20.0</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.20.0</version>
</dependency>
②创建spring和log4j2的配置文件
spring.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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.louis.ioc_xml.User"></bean>
</beans>
log4j2的配置文件可从取:https://blog.csdn.net/xry12354/article/details/131647570
③创建User对象
package com.louis.ioc_xml;/*** @author XRY* @date 2023年06月22日13:58*/
public class User {private String name;private Integer age;public void run(){System.out.println("run....");}
}
④获取Bean
方式一:根据id获取
由于id属性指定了bean的唯一标识,所以根据bean标签的id属性可以精确获取到一个组件对象。
写法:
<bean id="user" class="com.louis.ioc_xml.User"></bean>
id属性
:唯一标识
class属性
:要创建对象所在类的全路径(包名称+类名称)
@Test
public void testBeanById(){ApplicationContext applicationContext =new ClassPathXmlApplicationContext("bean.xml");User user = (User)applicationContext.getBean("user");logger.info("user = " + user);
}
/*[2023-06-22 14:17:20:953] [INFO] - TestBeanById.testBeanById(TestBeanById.java:20) - user = com.louis.ioc_xml.User@77d2e85*/
方式二:根据类型获取
@Test
public void testBeanByClass(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");User bean = applicationContext.getBean(User.class);logger.info("user"+bean);
}
/*[2023-06-22 14:22:24:009] [INFO] - TestBeanById.testBeanByClass(TestBeanById.java:29) - usercom.louis.ioc_xml.User@1a9c38eb*/
方式三:根据id和类型获取
@Test
public void testBeanByClassAndId(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");User user = applicationContext.getBean("user", User.class);logger.info("user" + user);
}
/*[2023-06-22 14:25:27:189] [INFO] - TestBeanById.testBeanByClassAndId(TestBeanById.java:37) - usercom.louis.ioc_xml.User@77d2e85*/
获取bean的细节
根据类型获取Bean时,要求IoC容器中指定类型的bean有且只能有一个。
组件类实现了接口,如果实现类只有一个则可以通过类型获取bean,如果实现类有多个,即使这些实现类都配置了bean也不能够使用类型获取。
只有一个实现类
//UserDaoImpl
package com.louis.bean;/*** @author XRY* @date 2023年06月22日14:37*/
public class UserDaoImpl implements UserDao{@Overridepublic void run() {System.out.println("check the target");}
}
测试
@Test
public void testInterface(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");UserDao userDao = applicationContext.getBean("userDao", UserDao.class);logger.info("userDao" + userDao);userDao.run();
}
/*[2023-06-22 14:43:27:092] [INFO] - TestBeanById.testInterface(TestBeanById.java:47) - userDaocom.louis.bean.UserDaoImpl@58ffcbd7check the target*/
User有多个实现类
//PersonDaoImpl
package com.louis.bean;/*** @author XRY* @date 2023年06月22日14:47*/
public class PersonDaoImpl implements UserDao{@Overridepublic void run() {System.out.println("person");}
}
测试
@Test
public void testTwoInterface(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");UserDao personDao = (UserDao)applicationContext.getBean("personDao");logger.info("personDao" + personDao);UserDao bean = applicationContext.getBean(UserDao.class);logger.info("bean" + bean);
}/*[2023-06-22 14:55:05:632] [INFO] - TestBeanById.testTwoInterface(TestBeanById.java:57) - personDaocom.louis.bean.PersonDaoImpl@555cf22org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.louis.bean.UserDao' available: expected single matching bean but found 2: userDao,personDao*/
结论
根据类型来获取bean
时,在满足bean唯一
性的前提下,其实只是看instanceof指定的类型的返回结果,只要返回的结果是true就可以认定为和类型匹配,能够获取到。
java中instanceof
运算符用来判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。
依赖注入
创建对象过程中,给属性设置值。
原生方法实现
package com.louis.di;/*** @author XRY* @date 2023年06月23日9:46*/
public class Book {private String name;private String author;public Book() {}public Book(String name, String author) {this.name = name;this.author = author;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public static void main(String[] args){//使用原生方法实现值的设置//setBook book = new Book();book.setName("西游记");book.setAuthor("吴承恩");//构造器Book book1 = new Book("水浒传","施耐庵");}
}
基于setter注入
步骤
1、创建类,定义属性生成属性的set方法
package com.louis.di;/*** @author XRY* @date 2023年06月23日9:46*/
public class Book {private String name;private String author;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +'}';}
}
2、在spring的配置文件中进行配置
<!--基于set方法进行注入-->
<bean id="book" class="com.louis.di.Book">
<!--在使用property这个标签时,就会调用类中的set方法--><property name="name" value="红楼梦"></property><property name="author" value="曹雪芹"></property>
</bean>
3、测试
@Test
public void testBook(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-di.xml");Book book = applicationContext.getBean("book", Book.class);logger.info("set注入" + book);
}/*[2023-06-23 10:02:10:517] [INFO] - TestBeanById.testBook(TestBeanById.java:72) - set注入Book{name='红楼梦', author='曹雪芹'}*/
基于构造器注入
步骤
1、创建类,定义属性,生成有参构造方法(可以没有无参)
package com.louis.di;/*** @author XRY* @date 2023年06月23日9:46*/
public class Book {private String name;private String author;public Book() {}public Book(String name, String author) {this.name = name;this.author = author;}@Overridepublic String toString() {return "Book{" +"name='" + name + '\'' +", author='" + author + '\'' +'}';}
}
2、在spring中进行配置
<!--构造器注入-->
<bean id="bookConstructor" class="com.louis.di.Book"><constructor-arg name="name" value="三国演义"></constructor-arg><constructor-arg name="author" value="罗贯中"></constructor-arg>
<!--也可以使用index这种类型<constructor-arg index="0" value="三国"></constructor-arg>-->
</bean>
3、测试
@Test
public void testConstructor(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-di.xml");Book bookConstructor = applicationContext.getBean("bookConstructor", Book.class);logger.info("bookCon" + bookConstructor);
}
/*有参构造方法执行了
[2023-06-23 10:13:15:457] [INFO] - TestBeanById.testConstructor(TestBeanById.java:81) - bookConBook{name='三国演义', author='罗贯中'}*/
注入过程中特殊值的处理
字面量赋值
字面量
:
如:int a = 1;直接赋值,表示我们看到的这个数据本身。
<!-- 使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量 -->
<property name="name" value="张三"/>
null值
<bean id="book" class="com.louis.di.Book">
<!--在使用property这个标签时,就会调用类中的set方法--><property name="name" value="红楼梦"></property><property name="author"><null></null></property>
</bean>
xml实体
当设置的值中有类似<>的时候,需要进行转义处理。解决方案:用xml实体来代替
<property name="name" value="<>"></property>
CDATA节
它是xml中一种特殊的写法,当设置的值中有类似<>的时候,就是要写<>时可以使用。
<property name="name"><!--CDATA节中写什么符号都随意--><value><![CDATA[ < >]]></value>
</property>
不同类型进行依赖注入
对象类型属性注入
如:部门和员工
Department
public class Department {private String dName;public void info(){System.out.println("Department name");}
}
Employee
public class Employee {private String eName;private Integer age;private Department dept;public void work(){System.out.println("Employee working");}
}
方式一:引用外部bean
1、生成它们的set方法
Department
//部门类
public class Department {private String dname;public String getDname() {return dname;}public void setDname(String dname) {this.dname = dname;}public void info(){System.out.println("Department name");}
}
Employee
public class Employee {private String eName;private Integer age;private Department dept;public String geteName() {return eName;}public void seteName(String eName) {this.eName = eName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Department getDept() {return dept;}public void setDept(Department dept) {this.dept = dept;}public void work(){System.out.println("Employee working");//为了验证引入是否成功dept.info();}
}
2、编写配置文件
<!--引入外部bean1、创建两个类对象:department和employee2、在Employee标签里面,使用property引入两个类-->
<bean id="dept" class="com.louis.di_test.Department"><property name="dname" value="IT"></property>
</bean>
<bean id="emp" class="com.louis.di_test.Employee"><property name="eName" value="Alex"></property><property name="age" value="18"></property>
<!--注入对象类型的熟属性--><property name="dept" ref="dept"></property>
</bean>
3、测试
@Test
public void testObj(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");Employee emp = applicationContext.getBean("emp", Employee.class);emp.work();logger.info("emp" + emp);
}
/*Employee working
Department name
[2023-06-23 11:45:56:941] [INFO] - TestBeanById.testObj(TestBeanById.java:92) - empEmployee{eName='Alex', age=18, dept=Department{dname='IT'}}
*/
方式二:内部bean
1、生成set方法
2、编写配置文件
<!--内部bean注入-->
<bean id="emp2" class="com.louis.di_test.Employee"><property name="eName" value="Louie"></property><property name="age" value="20"></property><!--内部bean--><property name="dept"><bean id="dept2" class="com.louis.di_test.Department"><property name="dname" value="设计"></property></bean></property>
</bean>
3、测试
@Test
public void testObj2(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");Employee emp2 = applicationContext.getBean("emp2", Employee.class);emp2.work();logger.info("emp2" + emp2);
}
/*
Employee working
Department name
[2023-06-23 11:54:58:543] [INFO] - TestBeanById.testObj2(TestBeanById.java:104) - emp2Employee{eName='Louie', age=20, dept=Department{dname='设计'}}
*/
方式三:级联属性赋值
1、创建实体对象,生成set方法
2、编写配置文件
<!--级联赋值-->
<bean id="dept3" class="com.louis.di_test.Department"><property name="dname" value="超人组"></property>
</bean>
<bean id="emp3" class="com.louis.di_test.Employee"><property name="eName" value="khan"></property><property name="age" value="23"></property><property name="dept" ref="dept3"></property><property name="dept.dname" value="研发科"></property>
</bean>
3、测试
@Test
public void testObj3(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diTest.xml");Employee emp3 = applicationContext.getBean("emp3", Employee.class);emp3.work();logger.info("emp3" + emp3);
}/*Employee working
Department name
[2023-06-23 12:02:44:654] [INFO] - TestBeanById.testObj3(TestBeanById.java:118) - emp3Employee{eName='khan', age=23, dept=Department{dname='研发科'}}*/
为数组类型属性赋值
1、编写实体类
public class Person {private String[] hobby;public String[] getHobby() {return hobby;}public void setHobby(String[] hobby) {this.hobby = hobby;}@Overridepublic String toString() {return "Person{" +"hobby=" + Arrays.toString(hobby) +'}';}
}
2、编写配置文件
<!--注入数组类型的属性-->
<bean id="person" class="com.louis.di_array.Person"><!--注入数组类型属性值--><property name="hobby"><array><value>eat</value><value>sleep</value><value>code</value></array></property>
</bean>
3、测试
@Test
public void testArray(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diarray.xml");Person person = applicationContext.getBean("person", Person.class);logger.info("person" + person);
}/*[2023-06-23 12:14:00:835] [INFO] - TestBeanById.testArray(TestBeanById.java:129) - personPerson{hobby=[eat, sleep, code]}*/
为集合类型属性赋值
(一)为list集合类型属性赋值
1、编写实体类并生成set方法
Department
public class Department {private String dname;private List<Employee> empList;public List<Employee> getEmpList() {return empList;}public void setEmpList(List<Employee> empList) {this.empList = empList;}public String getDname() {return dname;}public void setDname(String dname) {this.dname = dname;}public void info(){System.out.println("Department name");}@Overridepublic String toString() {return "Department{" +"dname='" + dname + '\'' +", empList=" + empList +'}';}
}
Employee
public class Employee {private String eName;private Integer age;private Department dept;public String geteName() {return eName;}public void seteName(String eName) {this.eName = eName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Department getDept() {return dept;}public void setDept(Department dept) {this.dept = dept;}public void work(){System.out.println("Employee working");dept.info();}@Overridepublic String toString() {return "Employee{" +"eName='" + eName + '\'' +", age=" + age +", dept=" + dept +'}';}
}
2、编写配置文件
<!--实现list集合注入-->
<bean id="emp" class="com.louis.di_test.Employee"><property name="eName" value="Louis"></property><property name="age" value="23"></property>
</bean>
<bean id="empTwo" class="com.louis.di_test.Employee"><property name="eName" value="Alex"></property><property name="age" value="22"></property>
</bean>
<bean id="dept" class="com.louis.di_test.Department"><property name="dname" value="研发科"></property><property name="empList"><list>
<!--如果是字符串和基本数据类型,可以直接使用<value>标签--><ref bean="emp"></ref><ref bean="empTwo"></ref></list></property>
</bean>
3、测试
@Test
public void testList(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-dilist.xml");Department dept = applicationContext.getBean("dept", Department.class);dept.info();logger.info("dept" + dept);
}/*Department name
employee.geteName() = Louis
employee.geteName() = Alex
[2023-06-23 12:31:05:121] [INFO] - TestBeanById.testList(TestBeanById.java:139) - deptDepartment{dname='研发科', empList=[Employee{eName='Louis', age=23, dept=null}, Employee{eName='Alex', age=22, dept=null}]}
*/
(二)为Map集合属性注入值
1、编写实体类并生成set方法
Student
public class Student {private String sname;private String sid;//一个学生可能对应多个老师private Map<String, Teacher> teacherMap;public Map<String, Teacher> getTeacherMap() {return teacherMap;}public void setTeacherMap(Map<String, Teacher> teacherMap) {this.teacherMap = teacherMap;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public String getSid() {return sid;}public void setSid(String sid) {this.sid = sid;}public void learn(){System.out.println("学生姓名" + sname + "----" + "学号" + sid);System.out.println(teacherMap);}@Overridepublic String toString() {return "Student{" +"sname='" + sname + '\'' +", sid='" + sid + '\'' +", teacherMap=" + teacherMap +'}';}
}
Teacher
public class Teacher {private String tname;private String tid;public String getTname() {return tname;}public void setTname(String tname) {this.tname = tname;}public String getTid() {return tid;}public void setTid(String tid) {this.tid = tid;}@Overridepublic String toString() {return "Teacher{" +"tname='" + tname + '\'' +", tid='" + tid + '\'' +'}';}
}
2、编写配置文件
<!--1、创建两个对象2、注入普通类型属性3、在学生bean注入map集合类型属性-->
<bean id="teacher" class="com.louis.di_map.Teacher"><property name="tid" value="110"></property><property name="tname" value="Alex"></property>
</bean>
<bean id="teacher2" class="com.louis.di_map.Teacher"><property name="tid" value="120"></property><property name="tname" value="Khan"></property>
</bean>
<bean id="student" class="com.louis.di_map.Student"><property name="sid" value="18162004"></property><property name="sname" value="Louie"></property><property name="teacherMap"><map><entry><key><value>key1</value></key><ref bean="teacher"></ref></entry><entry><key><value>key2</value></key><ref bean="teacher2"></ref></entry></map></property>
</bean>
3、测试
@Test
public void testMap(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diMap.xml");Student student = applicationContext.getBean("student", Student.class);logger.info("student" + student);student.learn();
}/*[2023-06-23 12:57:29:327] [INFO] - TestBeanById.testMap(TestBeanById.java:152) - studentStudent{sname='Louie', sid='18162004', teacherMap={key1=Teacher{tname='Alex', tid='110'}, key2=Teacher{tname='Khan', tid='120'}}}
学生姓名Louie----学号18162004
{key1=Teacher{tname='Alex', tid='110'}, key2=Teacher{tname='Khan', tid='120'}}*/
引用集合类型的bean
将list和map的实现方式换一种写法。
1、在原有的Student和Teacher的基础上,再添加一个Lesson类
public class Lesson {private String lessonName;public String getLessonName() {return lessonName;}public void setLessonName(String lessonName) {this.lessonName = lessonName;}@Overridepublic String toString() {return "Lesson{" +"lessonName='" + lessonName + '\'' +'}';}
}
2、再Student类中添加课程列表
List<Lesson> list;public List<Lesson> getList() {return list;
}public void setList(List<Lesson> list) {this.list = list;
}
3、编写配置文件
加上util的命名空间引入
<?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/utilhttp://www.springframework.org/schema/util/spring-util.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--1、创建三个对象2、注入普通类型属性3、使用util:类型 定义。需要更改命名空间引入4、在学生bean引入util:类型定义bean,完成list、map类型注入--><bean id="lessonOne" class="com.louis.di_map.Lesson"><property name="lessonName" value="JAVA开发"></property></bean><bean id="lessonTwo" class="com.louis.di_map.Lesson"><property name="lessonName" value="Python 开发"></property></bean><bean id="teacherOne" class="com.louis.di_map.Teacher"><property name="tname" value="Louie"></property><property name="tid" value="11011"></property></bean><bean id="teacherTwo" class="com.louis.di_map.Teacher"><property name="tname" value="Alex"></property><property name="tid" value="12012"></property></bean><bean id="student" class="com.louis.di_map.Student"><property name="sname" value="khan"></property><property name="sid" value="201811011"></property><!--注入list、map类型的属性--><property name="list" ref="lessonList"></property><property name="teacherMap" ref="teacherMap"></property></bean><util:list id="lessonList"><ref bean="lessonOne"></ref><ref bean="lessonTwo"></ref></util:list><util:map id="teacherMap"><entry><key><value>111</value></key><ref bean="teacherOne"></ref></entry><entry><key><value>222</value></key><ref bean="teacherTwo"></ref></entry></util:map>
</beans>
4、测试
@Test
public void testUtil(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diRef.xml");Student student = applicationContext.getBean("student", Student.class);student.learn();logger.info("student" + student);
}/*学生姓名khan----学号201811011
{111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}
[2023-06-23 14:28:04:062] [INFO] - TestBeanById.testUtil(TestBeanById.java:164) - studentStudent{sname='khan', sid='201811011', teacherMap={111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}, list=[Lesson{lessonName='JAVA开发'}, Lesson{lessonName='Python 开发'}]}
*/
p命名空间
命名空间:为避免命名时冲突,再命名后面加上:重命名的方式
xmlns:p = "http://www.springframework.org/schema/p"
编写配置文件
<!--p命名空间注入-->
<bean id="studentP" class="com.louis.di_map.Student" p:sid="201811" p:sname="Louis" p:list-ref="lessonList" p:teacherMap-ref="teacherMap">
</bean>
<util:list id="lessonList"><ref bean="lessonOne"></ref><ref bean="lessonTwo"></ref>
</util:list>
<util:map id="teacherMap"><entry><key><value>111</value></key><ref bean="teacherOne"></ref></entry><entry><key><value>222</value></key><ref bean="teacherTwo"></ref></entry>
</util:map>
测试
@Test
public void testP(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-diRef.xml");Student studentP = applicationContext.getBean("studentP", Student.class);studentP.learn();logger.info("studentP" + studentP);
}/*学生姓名Louis----学号201811
{111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}
[2023-06-23 14:43:14:562] [INFO] - TestBeanById.testP(TestBeanById.java:176) - studentPStudent{sname='Louis', sid='201811', teacherMap={111=Teacher{tname='Louie', tid='11011'}, 222=Teacher{tname='Alex', tid='12012'}}, list=[Lesson{lessonName='JAVA开发'}, Lesson{lessonName='Python 开发'}]}
*/
引入外部属性文件
应用场景:在一个文件中如果出现多个bean的创建和注入,维护就会比较困难。可以将一些特定的文件放在特定位置在spring中进行引入,如数据库文件。
实现步骤(数据库的配置文件引入)
1、引入相关依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.16</version>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.7</version>
</dependency>
2、创建Dbutils.properties
username=root
password=root
url=jdbc:mysql://localhost:3306/spring
driver=com.mysql.cj.jdbc.Driver
3、创建spring的配置文件
引入context命名空间,引入属性文件,使用表达式完成注入。
context命名空间
xmlns:contex="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
引入属性文件
<!--引入外部属性文件-->
<contex:property-placeholder location="classpath:Dbutils.properties"></contex:property-placeholder>
完整配置
<?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:contex="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--引入外部属性文件--><contex:property-placeholder location="classpath:Dbutils.properties"></contex:property-placeholder>
<!--完成数据库信息注入--><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="${url}"></property><property name="username" value="${username}"></property><property name="password" value="${password}"></property><property name="driver" value="${driver}"></property></bean>
</beans>
4、测试
@Test
public void testDbutils(){ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-Dbutils.xml");DruidDataSource dataSource = applicationContext.getBean("druidDataSource", DruidDataSource.class);logger.info("dataSource" + dataSource);
}
/*
* [2023-06-23 15:36:52:008] [INFO] - TestBeanById.testDbutils(TestBeanById.java:189) - dataSource{CreateTime:"2023-06-23 15:36:51",ActiveCount:0,PoolingCount:0,CreateCount:0,DestroyCount:0,CloseCount:0,ConnectCount:0,Connections:[]
}
* */