Spring——IOC底层原理

时间:2024-10-09 07:59:21

目录

一、IOC底层原理

1.什么是IOC

底层原理

二、IOC接口(BeanFanctory)

三、IOC操作Bean管理(基于XML)

1.创建对象

2.注入属性

(1)DI:依赖注入

(2)p名称空间注入(了解)

(3)注入其他类型属性

(4)注入外部bean 

(5)注入内部bean和级联赋值

(6)注入集合类型

 4.属性注入细节


一、IOC底层原理

1.什么是IOC

        通过控制反转(Inversion of Control,缩写为IOC),对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

        1)控制反转,把对象的创建和对象之间调用的过程,交给Spring进行管理

        2)使用IOC目的:降低耦合度

        3)入门案例即为IOC的实现(入门案例:【网址】)

底层原理

(1)XML解析 + 工厂设计模式 + 反射(令耦合度尽可能的降低到最小)

通过画图来讲解IOC底层原理:

二、IOC接口(BeanFanctory)

  1. IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
  2. Spring提供IOC容器实现的两种方式(两个接口,两个接口均可加载XML文件并且获取配置创建的对象):

        (1)BeanFactory:IOC容器基本实现方式,是Spring内部使用的接口,不提供开发人员使用。

                特点:加载配置文件时不会创建对象,而是在获取对象或者使用对象时才去创建对象。

        (2)ApplicationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般面向开发人员使用。

                特点:加载配置文件时,直接创建对象。

 ApplicationContext中有两个主要的实现类:

1. FileSystemXmlApplicationContext:括号中时配置文件的全路径。

2. ClassPathXmlApplicationContext:括号中直接配置文件名。

三、IOC操作Bean管理(基于XML)

Bean管理(两个操作):

        (1)Spring创建对象

        (2)Spring属性注入

1.创建对象

                

                a. 在Spring配置文件中,使用bean标签,标签里面添加对应的属性,就可以实现对象创建。

                b. 在bean标签中有很多属性,常见的有:

                * id 属性:设置类的唯一标识(并不是直接指对象名称);

                * Class属性 :类全路径(包类路径);

                c. 创建对象的时候,默认执行无参构造器方法(若使用有参构造器,且未构成无参构造器,此时无参构造器被覆盖,所以常规获取对象方式报错)

2.注入属性

(1)DI:依赖注入

是AOC的一种具体实现,必须在创建对象的基础之上完成。

 * 第一种注入方式:set方法注入

i.

  1. /**
  2. * 演示使用set方法进行属性注入
  3. */
  4. public class Book {
  5. //创建属性
  6. private String bname;
  7. private String bauthor;
  8. //创建属性对应的set方式注入
  9. public void setBname(String bname) {
  10. this.bname = bname;
  11. }
  12. public void setBauthor(String bauthor) {
  13. this.bauthor = bauthor;
  14. }
  15. public void TestBook(){
  16. (bname + " :: "+bauthor);
  17. }
  18. }

 ii.在Spring配置文件中配置对象创建,配置属性注入

  1. <bean id="Book" class="">
  2. <!--使用property完成属性注入
  3. name:类里面的属性名称
  4. value:向属性注入的值
  5. -->
  6. <property name="bname" value="数据结构"></property>
  7. <property name="bauthor" value="xxx"></property>
  8. </bean>

iii. 测试代码 

  1. public void TestBook(){
  2. ApplicationContext context =
  3. new ClassPathXmlApplicationContext("");
  4. Book book = ("Book", );
  5. ();
  6. }

输出结果:

第二种注入方式:使用有参构造器注入

  1. package ;
  2. /**
  3. * 演示使用有参构造来进行属性注入
  4. */
  5. public class Orders {
  6. private String oname;
  7. private String address;
  8. public Orders(String oname, String address) {
  9. this.oname = oname;
  10. this.address = address;
  11. }
  12. public void Test(){
  13. (oname + ":" + address);
  14. }
  15. }
  1. <bean id="Oders" class="">
  2. <constructor-arg name="oname" value="abc"></constructor-arg>
  3. <constructor-arg name="address" value="123"></constructor-arg>
  4. </bean>
  1. @Test
  2. public void TestOrder(){
  3. ApplicationContext context =
  4. new ClassPathXmlApplicationContext("");
  5. Orders oders = ("Oders", );
  6. ();
  7. }

(2)p名称空间注入(了解)

        a. 使用p名称空间注入,可以简化基于xml配置方式

第一步:添加 p 名称空间在配置文件中

第二步:进行属性注入,在bean标签中进行操作

  1. <bean id="Book" class="" p:bname="高频电子线路" p:bauthor="周珩">
  2. </bean>

测试:

  1. @Test
  2. public void TestBook() {
  3. ApplicationContext context =
  4. new ClassPathXmlApplicationContext("");
  5. Book book = ("Book", );
  6. ();
  7. }

 结果:

(3)注入其他类型属性

1.字面量

    (1)null

  1. <bean id="Book" class="">
  2. <!--设置一个空值-->
  3. <property name="bname" value="数据结构"></property>
  4. <property name="bauthor">
  5. <null/>
  6. </property>
  7. </bean>

    (2)特殊符号

  1. <bean id="Book" class="">
  2. <!--属性值包含特殊符号
  3. 1.把<>进行转义 &lt;&gt;
  4. <property name="bauthor" value="&lt;&gt;<<南京>>"></property>
  5. 2.把带特殊符号的内容写道CDATA
  6. -->
  7. <property name="bauthor" >
  8. <value><![CDATA[<<南京>>]]></value>
  9. </property>
  10. </bean>

(4)注入外部bean 

a.创建Service类和Dao类

b.在Service类中调用Dao类中的方法

c.在Spring配置文件中进行配置

  1. //测试
  2. @Test
  3. public void TestBean1(){
  4. ApplicationContext context =
  5. new ClassPathXmlApplicationContext("");
  6. UserService userService = ("userService", );
  7. ();
  8. }
  9. /*结果:
  10. 运行.....
  11. 运行....
  12. */

(5)注入内部bean和级联赋值

 a.一对多关系:部门和员工(一个部门有多个员工,一个员工属于一个部门);

b.在实体类之间标识一对多(员工表示所属部门),使用对象类型属性进行表示;

c.在Spring配置文件中进行配置

  1. public void TestBean_(){
  2. ApplicationContext context =
  3. new ClassPathXmlApplicationContext("Bean_.xml");
  4. Emp emp = ("emp", );
  5. ();
  6. }
  7. /*结果:
  8. id = 1 ename = xx dept = Dept{dname='研发部'}
  9. */

注:配置文件也可以使用级联赋值的方式

也可以这样写: 但注意此时的结果: 

已经将bean标签中的value值覆盖!!!

(6)注入集合类型

集合类型(List、Map、Set)

1.注入数组类型属性

2.注入list集合属性

3.注入Map集合类型的属性

(1)创建类,定义数组、list、map、set集合类型属性,并生成对应的set方法

  1. package .;
  2. import ;
  3. import ;
  4. import ;
  5. public class Stu {
  6. //1.数组类型属性
  7. private String[] course;
  8. //集合类型属性
  9. private List<String> list;
  10. //集合类型的属性
  11. private Map<String, String> mapS;
  12. //集合类型属性
  13. private Set<String> sets;
  14. public void setCourse(String[] course) {
  15. this.course = course;
  16. }
  17. public void setList(List<String> list) {
  18. this.list = list;
  19. }
  20. public void setMapS(Map<String, String> mapS) {
  21. this.mapS = mapS;
  22. }
  23. public void setSets(Set<String> sets) {
  24. this.sets = sets;
  25. }
  26. public void test(){
  27. ((course));
  28. ("===============");
  29. (list);
  30. ("===============");
  31. (maps);
  32. ("===============");
  33. (sets);
  34. }
  35. }

(2)在Spring配置文件中进行配置

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="/schema/beans"
  3. xmlns:xsi="http:///2001/XMLSchema-instance"
  4. xsi:schemaLocation="/schema/beans /schema/beans/">
  5. <bean id="stu" class=".">
  6. <!--1.数组类型注入-->
  7. <property name="course" >
  8. <array>
  9. <value>英语</value>
  10. <value>语文</value>
  11. <value>数学</value>
  12. <value>历史</value>
  13. </array>
  14. </property>
  15. <!--list集合类型注入-->
  16. <property name="list" >
  17. <array>
  18. <value>张三</value>
  19. <value>三三</value>
  20. </array>
  21. </property>
  22. <!--map集合类型注入-->
  23. <property name="maps">
  24. <map>
  25. <entry key="1" value="数学"></entry>
  26. <entry key="2" value="语文"></entry>
  27. </map>
  28. </property>
  29. <!--set集合类型注入-->
  30. <property name="sets">
  31. <set>
  32. <value>mysql</value>
  33. <value>java</value>
  34. </set>
  35. </property>
  36. </bean>
  37. </beans>
  1. //测试
  2. package .;
  3. import .;
  4. import ;
  5. import ;
  6. public class Test {
  7. @org.
  8. public void TestBeanArray(){
  9. ApplicationContext context = new ClassPathXmlApplicationContext("");
  10. Stu stu = ("stu", );
  11. ();
  12. }
  13. }
  14. /*结果:
  15. [英语, 语文, 数学, 历史]
  16. ===============
  17. [张三, 三三]
  18. ===============
  19. {1=数学, 2=语文}
  20. ===============
  21. [mysql, java]
  22. */

 4.属性注入细节

1.若集合中储存对象类型的值

(比如每个学生可以学多门课程,创建Course类,并且在Stu类中创建list集合来储存多个course对象,再构建其对应的set方法)

  1. package .;
  2. public class Course {
  3. private String cname;
  4. public void setCname(String cname) {
  5. this.cname = cname;
  6. }
  7. }

在配置文件中配制时,首先创建多个course对象

  1. <!--创建多个course对象-->
  2. <bean id="course1" class=".">
  3. <property name="cname" value="数据结构"></property>
  4. </bean>
  5. <bean id="course2" class=".">
  6. <property name="cname" value="Spring5"></property>
  7. </bean>

再使用外部标签注入

  1. <!--list对象类型值注入-->
  2. <property name="courseList">
  3. <list>
  4. <ref bean="course1"></ref>
  5. <ref bean="course2"></ref>
  6. </list>
  7. </property>

2.不同类中,用到相同的集合类型(目前的配置文件的说明只注入一个类中,解决方法:将list结合的配置提取,做成公共部分,让所有的类均能引入该集合)

(1)在Spring配置中先引入一个名称空间 (util)

(2)使用Util标签完成list集合注入提取

【关于IOC操作Bean管理(基于beanFactory)笔记可转:】