Spring——IOC底层原理
目录
一、IOC底层原理
1.什么是IOC
2.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的实现(入门案例:【网址】)
2.IOC底层原理
(1)XML解析 + 工厂设计模式 + 反射(令耦合度尽可能的降低到最小)
通过画图来讲解IOC底层原理:
二、IOC接口(BeanFanctory)
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
- 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.
/*** 演示使用set方法进行属性注入*/
public class Book {//创建属性private String bname;private String bauthor;//创建属性对应的set方式注入public void setBname(String bname) {this.bname = bname;}public void setBauthor(String bauthor) {this.bauthor = bauthor;}public void TestBook(){System.out.println(bname + " :: "+bauthor);}
}
ii.在Spring配置文件中配置对象创建,配置属性注入
<bean id="Book" class="com.xx.Spring.Book"><!--使用property完成属性注入name:类里面的属性名称value:向属性注入的值--><property name="bname" value="数据结构"></property><property name="bauthor" value="xxx"></property>
</bean>
iii. 测试代码
public void TestBook(){ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");Book book = context.getBean("Book", Book.class);book.TestBook();
}
输出结果:
* 第二种注入方式:使用有参构造器注入
package com.xx.Spring.testDome;/*** 演示使用有参构造来进行属性注入*/
public class Orders {private String oname;private String address;public Orders(String oname, String address) {this.oname = oname;this.address = address;}public void Test(){System.out.println(oname + ":" + address);}
}
<bean id="Oders" class="com.xx.Spring.testDome.Orders"><constructor-arg name="oname" value="abc"></constructor-arg><constructor-arg name="address" value="123"></constructor-arg>
</bean>
@Test
public void TestOrder(){ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");Orders oders = context.getBean("Oders", Orders.class);oders.Test();
}
(2)p名称空间注入(了解)
a. 使用p名称空间注入,可以简化基于xml配置方式
第一步:添加 p 名称空间在配置文件中
第二步:进行属性注入,在bean标签中进行操作
<bean id="Book" class="com.xx.Spring.Book" p:bname="高频电子线路" p:bauthor="周珩"></bean>
测试:
@Test
public void TestBook() {ApplicationContext context =new ClassPathXmlApplicationContext("bean1.xml");Book book = context.getBean("Book", Book.class);book.TestBook();
}
结果:
(3)注入其他类型属性
1.字面量
(1)null
<bean id="Book" class="com.xx.Spring.Book"><!--设置一个空值--><property name="bname" value="数据结构"></property><property name="bauthor"><null/></property>
</bean>
(2)特殊符号
<bean id="Book" class="com.xx.Spring.Book"><!--属性值包含特殊符号1.把<>进行转义 <><property name="bauthor" value="<><<南京>>"></property>2.把带特殊符号的内容写道CDATA--><property name="bauthor" ><value><![CDATA[<<南京>>]]></value></property>
</bean>
(4)注入外部bean
a.创建Service类和Dao类
b.在Service类中调用Dao类中的方法
c.在Spring配置文件中进行配置
//测试
@Test
public void TestBean1(){ApplicationContext context =new ClassPathXmlApplicationContext("Bean1.xml");UserService userService = context.getBean("userService", UserService.class);userService.add();
}/*结果:
Service.add运行.....
Dao.updata运行....
*/
(5)注入内部bean和级联赋值
a.一对多关系:部门和员工(一个部门有多个员工,一个员工属于一个部门);
b.在实体类之间标识一对多(员工表示所属部门),使用对象类型属性进行表示;
c.在Spring配置文件中进行配置
public void TestBean_(){ApplicationContext context =new ClassPathXmlApplicationContext("Bean_.xml");Emp emp = context.getBean("emp", Emp.class);emp.add();
}/*结果:
id = 1 ename = xx dept = Dept{dname='研发部'}
*/
注:配置文件也可以使用级联赋值的方式
也可以这样写: 但注意此时的结果:
已经将bean标签中的value值覆盖!!!
(6)注入集合类型
集合类型(List、Map、Set)
1.注入数组类型属性
2.注入list集合属性
3.注入Map集合类型的属性
(1)创建类,定义数组、list、map、set集合类型属性,并生成对应的set方法
package com.xx.Spring2.collectionType;
import java.util.List;
import java.util.Map;
import java.util.Set;public class Stu {//1.数组类型属性private String[] course;//2.List集合类型属性private List<String> list;//3.Map集合类型的属性private Map<String, String> mapS;//4.Set集合类型属性private Set<String> sets;public void setCourse(String[] course) {this.course = course;}public void setList(List<String> list) {this.list = list;}public void setMapS(Map<String, String> mapS) {this.mapS = mapS;}public void setSets(Set<String> sets) {this.sets = sets;}public void test(){System.out.println(Arrays.toString(course));System.out.println("===============");System.out.println(list);System.out.println("===============");System.out.println(maps);System.out.println("===============");System.out.println(sets);}
}
(2)在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"><bean id="stu" class="com.xx.Spring2.collectionType.Stu"><!--1.数组类型注入--><property name="course" ><array><value>英语</value><value>语文</value><value>数学</value><value>历史</value></array></property><!--list集合类型注入--><property name="list" ><array><value>张三</value><value>三三</value></array></property><!--map集合类型注入--><property name="maps"><map><entry key="1" value="数学"></entry><entry key="2" value="语文"></entry></map></property><!--set集合类型注入--><property name="sets"><set><value>mysql</value><value>java</value></set></property>
</bean></beans>
//测试
package com.xx.Spring2.TestArray;import com.xx.Spring2.collectionType.Stu;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {@org.junit.Testpublic void TestBeanArray(){ApplicationContext context = new ClassPathXmlApplicationContext("beanArray.xml");Stu stu = context.getBean("stu", Stu.class);stu.test();}
}
/*结果:
[英语, 语文, 数学, 历史]
===============
[张三, 三三]
===============
{1=数学, 2=语文}
===============
[mysql, java]
*/
4.属性注入细节
1.若集合中储存对象类型的值
(比如每个学生可以学多门课程,创建Course类,并且在Stu类中创建list集合来储存多个course对象,再构建其对应的set方法)
package com.xx.Spring2.collectionType;public class Course {private String cname;public void setCname(String cname) {this.cname = cname;}
}
在配置文件中配制时,首先创建多个course对象
<!--创建多个course对象-->
<bean id="course1" class="com.xx.Spring2.collectionType.Course"><property name="cname" value="数据结构"></property>
</bean>
<bean id="course2" class="com.xx.Spring2.collectionType.Course"><property name="cname" value="Spring5"></property>
</bean>
再使用外部标签注入
<!--list对象类型值注入-->
<property name="courseList"><list><ref bean="course1"></ref><ref bean="course2"></ref></list>
</property>
2.不同类中,用到相同的集合类型(目前的配置文件的说明只注入一个类中,解决方法:将list结合的配置提取,做成公共部分,让所有的类均能引入该集合)
(1)在Spring配置中先引入一个名称空间 (util)
(2)使用Util标签完成list集合注入提取
【关于IOC操作Bean管理(基于beanFactory)笔记可转:】
Spring——IOC底层原理相关推荐
- 10. Spring IOC 底层原理
Spring IOC 底层原理 如何通过 IOC 容器来创建对象: 创建 Maven 工程,在 pom.xml 中添加 Spring 框架相关的依赖: 新建实体类: 在 resources 目录下创建 ...
- spring 学习—spring 的ioc底层原理(02)
IOC的底层原理 1.ioc底层原理使用技术 (1) xml配置文件 (2) dom4j 解决xml (3)工厂设计模式 (4)反射 什么叫做耦合度太高了:就是关联度太紧密了 高内聚与低耦合 高内聚: ...
- Spring IOC核心原理分析
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,本文系统分 ...
- 【JAVA SE】第十七章 反射、注解与Spring事务底层原理
第十七章 反射.注解与Spring事务底层原理 文章目录 第十七章 反射.注解与Spring事务底层原理 一.反射 1.简介 2.意义 3.缺点 4.应用场景 5.反射技术的使用 二.注解 1.概念 ...
- Spring Cloud底层原理(转载 石杉的架构笔记)
拜托!面试请不要再问我Spring Cloud底层原理 原创: 中华石杉 石杉的架构笔记 目录 一.业务场景介绍 二.Spring Cloud核心组件:Eureka 三.Spring Cloud核心组 ...
- 还不懂spring IOC核心原理?200行代码带你手撸一个
Spring做为Java企业级应用的开源开发框架,早已成为Java后端开发事实上的行业标准,无数的公司选择Spring作为基础的开发框架. 使用Spring框架的人一定都听过Spring的IoC(控制 ...
- Spring Boot底层原理详解及整合
Spring Boot框架 通过Spring Boot 可以构建一个基于Spring框架的Java Application,简化配置,自动装配,开箱即用 JavaConfiguration用Java类 ...
- Spring IoC Container 原理解析
IoC.DI基础概念 关于IoC和DI大家都不陌生,我们直接上martin fowler的原文,里面已经有DI的例子和spring的使用示例 <Inversion of Control Cont ...
- 面试官:说说Spring Cloud底层原理?
点击上方"蓝字", 右上角选择"设为星标" 周一至周五上午11:45!精品文章准时送上! 本文转载自公众号:石杉的架构笔记 目录 一.业务场景介绍 二.Spri ...
最新文章
- 动态语言的灵活性是把双刃剑 -- 以Python语言为例
- electron 托盘图标闪烁_从零到一,用 Electron 开发桌面效率工具
- bzoj4830 hnoi2017 抛硬币
- 1112-博客十大评论
- VTK:可视化之NormalsDemo
- windows下apk查看工具的原理
- 数据加密算法的简介与应用
- html中input不可编辑状态,css如何实现input不可编辑
- 计算机网络学习笔记(七)——传输层、TCP三次握手、四次挥手、TCP流量控制、大总结
- Python联网下载文件
- workbook加载文件路径_【Python】文件重命名(按照Excel清单)
- CentOS 7.2 终端安装字体
- oracle学习资料pdf
- Tahoma Arial Verdana三种字体的选择
- 过去分词和动词过去式区别
- 封装、private、this、 setter/gette、构造方法和标准类的定义
- C语言中如何定义全局变量
- std::accumulate的用法
- 如何利用福禄克FLUKE 718 校准压力开关
- 07.保护模式下字符显示
热门文章
- office多级列表编号设置
- Windows 10系统下安装Go语言环境
- linux在没网的情况下安装libreoffice
- 学习STM32 Flash存储 W25Q64 SPI总线存储模块进行读写数据
- macbook历代_盘点历代苹果笔记本,简直就是一部MacBook瘦身史
- java applet无法运行,错误: 找不到或无法加载主类 sun.applet.AppletViewer
- EMC VNX5000系列NAS配置手册
- 在java中使用SFTP协议安全的传输文件
- smartform解决越南文预览正常 打印后字符乱码
- 向热爱计算机科学的你推荐SICP