IOC(概念和原理)
文章目录
- 1. IOC容器概念
- 2. IOC底层原理
- 3. IOC(接口)
- 4. IOC操作Bean管理(概念)
- 5. IOC操作Bean管理(基于xml方式)
- 5.1 基于xml创建对象
- 5.2 基于xml方式注入属性
- 5.2.1 DI:依赖注入,就是注入属性
- 5.2.2 xml注入其他类型属性
- 5.2.3 注入属性-外部bean
- 5.2.4 注入属性-内部bean(很多人喜欢用外部bean,结构明显)
- 5.2.5 注入属性-级联赋值
- 5.2.6 xml注入集合属性(数组、List、Map、Set)
- 6. IOC操作Bean管理(FactoryBean)
- 7、IOC操作Bean管理(bean作用域)
- 8. IOCBean管理(bean生命周期)
- 9. IOC操作Bean管理(xml自动装配)
- 10. IOC操作Bean管理(外部属性文件)
- 11. IOC操作Bean管理(基于注解方式:简化xml配置)
- 12. 基于注解方式实现属性注入
- 13. 完全注解开发
1. IOC容器概念
- 控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理。
- 使用IOC目的:为了耦合度降低
2. IOC底层原理
- XML解析、工厂设计模式、反射
- IOC过程
- 第一步:xml配置文件,配置创建的对象
<bean id="dao" class="com.zsh.UserDao"></bean>- 第二步:有service类和dao类,创建工厂类
class UserFactory{public static UserDao getDao(){//1.xml解析 String classValue = class属性值; //2.通过反射创建对象Class clazz = Class.forName(classValue);return (UserDao)clazz.getDeclaredConstructor().newInstance();} }
3. IOC(接口)
- IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
- Spring提供IOC容器实现方式:(两个接口)
- BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用。
加载配置获取文件时候不会创建对象,在获取对象(使用)才去创建对象。 - ApplocationContext:BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用。
加载配置文件时候就会把在配置文件中的对象进行创建。
- BeanFactory:IOC容器基本实现,是Spring内部的使用接口,不提供开发人员进行使用。
- ApplicationContext接口有实现类

4. IOC操作Bean管理(概念)
- 什么是Bean管理? Bean管理有两方面
- Spring创建对象
- Spring注入属性
- Bean管理操作有两种方式
- 基于xml配置文件方式实现
- 基于注解方式实现
5. IOC操作Bean管理(基于xml方式)
5.1 基于xml创建对象
<!-- 配置User对象 -->
<bean id="user" class="com.spring.User"></bean>
- 在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建
- 在bean标签有很多属性,介绍常用的属性
- id属性:唯一标识
- class属性:类全路径(包类路径)
- 创建对象时候,默认也是执行无参数构造方法完成对象创建。
5.2 基于xml方式注入属性
5.2.1 DI:依赖注入,就是注入属性
- 第一种注入方式:set注入方式
- 创建类,定义属性和对应的set方法
- 在spring配置文件中配置对象创建,配置属性注入。
<bean id="book" class="zsh.spring.Book"><!--2.set方法注入属性--><!--name:类里面属性名称value:向属性注入的值--><property name="bname" value="天龙八部"></property><property name="bauthor" value="金庸"></property> </bean> - 第二种注入方式:有参数构造方式
- 创建类,定义属性,创建属性对应有参构造方法。
- 在spring配置文件中配置。
```xml
<!--3.有参构造注入属性-->
<bean id="orders" class="zsh.spring.Orders"><constructor-arg name="oname" value="abc"></constructor-arg><constructor-arg name="address" value="China"></constructor-arg>
</bean>
```
- p名称空间注入(了解)
- 使用p名称空间注入,可以简化基于xml配置方式。
<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">- 进行属性注入,在bean标签里面进行操作。
5.2.2 xml注入其他类型属性
- 字面量
- null值
<property name="address"><null></null> </property>- 属性值包含特殊符号
<!--属性值包含特殊符号1.把《》进行转义2.把带特殊符号内容写到CDATA中--> <property name="bname"><value><![CDATA[《天龙八部》]]></value> </property>
5.2.3 注入属性-外部bean
- 创建两个类service类和dao类
- 在service调用到里面的方法
public interface UserDao {public abstract void update();} public class UserDaoImpl implements UserDao {@Overridepublic void update() {System.out.println("dao update....");} } public class UserService {private UserDao userDao;public void setUserDao(UserDao userDao){this.userDao = userDao;}public void add(){System.out.println("service add .....");userDao.update();} } - 在xml中配置
<!-- 1 service和dao对象创建 --> <bean id="userService" class="zsh.service.UserService"><!--name属性:类里面的属性名称ref属性:创建userDaoImpl对象bean标签--><property name="userDao" ref="userDaoImpl"></property> </bean> <bean id="userDaoImpl" class="zsh.dao.Impl.UserDaoImpl"></bean>
5.2.4 注入属性-内部bean(很多人喜欢用外部bean,结构明显)
- 一对多关系:部门和员工(一个部门多个员工,一个员工属于某一个部门 )
- 在实体类之间表示一对多关系,员工表示所属部门,使用对象类型属性进行表示
//部门类 public class Dept {private String dname;public void setDname(String dname) {this.dname = dname;} } //员工类 public class Emp {private String ename;private String gender;//员工属于某一个部门private Dept dept;public void setDept(Dept dept) {this.dept = dept;}public void setEname(String ename) {this.ename = ename;}public void setGender(String gender) {this.gender = gender;} } - 在spring配置中进行配置。
<!-- 内部bean --> <bean id="emp" class="zsh.bean.Emp"><property name="ename" value="lucky"></property><property name="gender" value="女"></property><property name="dept"><bean id="dept" class="zsh.bean.Dept"><property name="dname" value="安保部"></property></bean></property> </bean>
5.2.5 注入属性-级联赋值
- 方式一:同外部bean注入
- 方式二:xml配置如下(需要在emp表给dept设置getter)
<!-- 级联赋值 --> <bean id="emp" class="zsh.bean.Emp"><property name="ename" value="lucky"></property><property name="gender" value="女"></property><property name="dept" ref="dept"></property><property name="dept.dname" value="技术部"></property> </bean> <bean id="dept" class="zsh.bean.Dept"><property name="dname" value="安保部"></property> </bean>
5.2.6 xml注入集合属性(数组、List、Map、Set)
- 创建类、定义数组、List、Map、Set类型属性,生成对应set方法。
public class Stu {private String[] courses;private List<String> list;private Map<String,String> maps;private Set<String> sets;public void setCourses(String[] courses){this.courses = courses;}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;} } - 在Spring配置文件进行配置。
<!-- 集合类型属性注入 --> <bean id="stu" class="zsh.shuzu.Stu"><!-- 数组类型属性注入 --><property name="courses"><array><value>java</value></array></property><!-- list类型属性注入,值是对象类型 --><property name="list"><list><ref bean="course1"></ref><ref bean="course2"></ref></list></property><!-- Map类型属性注入 --><property name="maps"><map><entry key="JAVA" value="java"></entry></map></property><!-- Set类型属性注入 --><property name="sets"><set><value>MySql</value></set></property> </bean> <!--创建多个Course对象--> <bean id="course1" class="zsh.shuzu.Course"><property name="cname" value="Spring5框架"></property> </bean> <bean id="course2" class="zsh.shuzu.Course"><property name="cname" value="Mybatis框架"></property> </bean> - 把集合注入部分提取出来。
- 在spring配置文件中引入名称空间util
<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"xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">- 使用标签完成list集合注入提取
<util:list id="bookList"><ref bean="course1"></ref> </util:list> <!-- list类型属性注入,值是对象 --> <property name="courseList" ref="bookList"></property>
注意:面试中会问DI 和 IOC区别?
DI 是 IOC中一种具体实现,就表示依赖注入(注入属性),注入属性需要在创建对象的基础之上。
6. IOC操作Bean管理(FactoryBean)
Spring有两种类型bean,一种普通bean,另一种工厂bean(FactoryBean)
- 普通bean:在配置文件中定义bean类型就是返回类型(上面的配置bean就是普通bean)
- 工厂bean:在配置文件定义bean类型可以和返回值类型不一样
- 第一步:创建类,让这个类作为工厂bean,实现接口FactoryBean
- 第二步:实现接口里面的方法,在实现的方法中定义返回的bean类型
public class MyBean implements FactoryBean<Course> {//定义返回bean@Overridepublic Course getObject() throws Exception {Course course = new Course();course.setCname("abc");return course;}@Overridepublic Class<?> getObjectType() {return null;} }
7、IOC操作Bean管理(bean作用域)
- 在Spring里面,设置创建bean实例默认为单实例对象
- 如何设置单实例还是多实例?
- 在spring配置文件bean标签里面有属性(scope)用于设置scope属性值:
- 默认值sigleton,表示单实例对象 ;
- prototype,表示多实例对象。
- 注意: sigleton和prototype区别?
第一:sigleton单实例,prototype多实例
第二:设置scope是sigleton时候,加载spring配置文件时候就会创建单实例对象。
第三:设置scope是prototype时候,不是在加载spring配置文件时候创建对象,在调用getBean方法时候创建多实例对象。
- 在spring配置文件bean标签里面有属性(scope)用于设置scope属性值:
8. IOCBean管理(bean生命周期)
- 生命周期:从对象创建到对象销毁的过程
- bean生命周期五步(配置后置处理器七步)
- 通过构造器创建bean实例(无参数构造)
- 为bean的属性设置值和对其它bean引用(调用set方法)
- 调用bean的初始化的方法(需要进行配置初始化的方法)
- bean可以使用了(对象获取到了)
- 当容器关闭时候,调用bean的销毁的方法(需要进行配置销毁的方法)
<bean id="xxx" class="xxx" init-method="initMethod" destroy-method="destroyMethod">
- bean的后置处理器,bean生命周期有七步(创建类实现BeanPostProcessor并在xml配置成bean)
- 把bean实例传递bean后置处理器的方法(调用类的before)
- 调用bean的初始化的方法(需要进行配置初始化的方法)
- 把bean实例传递bean后置处理器的方法(调用类的after)
9. IOC操作Bean管理(xml自动装配)
- 什么是自动装配?
根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入。 - spring文件中配置(Emp中有Dept属性)
<!--实现自动装配autowire属性常用两个值:byName根据属性名称注入 注入bean的id值和类的属性名称一样byType根据属性类型注入
-->
<bean id="emp" class="autowire.Emp" autowire="byName"></bean>
<bean id="dept" class="zsh.autowire.Dept"></bean>
10. IOC操作Bean管理(外部属性文件)
- 直接配置数据库信息(不展示了)
- 引入外部属性文件配置数据库连接池(德鲁伊连接池)
<!-- 引入外部属性文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="${jdbc.driverClassName}"></property><property name="url" value="${jdbc.url}"></property><property name="username" value="${jdbc.username}"></property><property name="password" value="${jdbc.password}"></property>
</bean>
11. IOC操作Bean管理(基于注解方式:简化xml配置)
- Spring针对Bean管理中创建对象提供注解
@Component(value=“”)
@Service(value=“”)
@Controller(value=“”)
@Repository(value=“userDaoImp”)
上面四个注解功能是一样的,都可以用来创建bean实例 - 基于注解方式实现对象创建
- 第一步:引入aop依赖jar包
- 第二步:开启组件扫描
<!--1 如果扫描多个包,多个包使用逗号隔开 ;2.扫描包上层目录--><context:component-scan base-package=""/> - 第三步:创建类,在类上面添加创建对象注解
注意:开启组件扫描细节配置<!--示例一use-default-filters="false 表示现在不使用默认filter,自己配置filtercontext:include-filter 表示扫描包下Controller注解 --> <context:component-scan base-package="com" use-default-filters="false"><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan><!-- 设置不去扫描哪些内容 --> <context:component-scan base-package="com"><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
12. 基于注解方式实现属性注入
- Spring提供的注解
@AutoWired:根据属性类型进行自动装配
@Qualifier(value=“userDaoImp”):根据属性名称进行自动装配(和@Autowired一起使用)
@Reaource(name=“userDaoImp”):可以根据类型注入,也可以根据名称注入
注意:此注解的包是javax中的,不是spring中的
@Value:注入普通类型属性
13. 完全注解开发
- 创建配置类,替代xml配置文件
@Configuration //配置类,替代xml配置文件@ComponentSean(basePackage={}) //包扫描public class SpringConfig{
}
- 编写测试类
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

相关文章:
IOC(概念和原理)
文章目录1. IOC容器概念2. IOC底层原理3. IOC(接口)4. IOC操作Bean管理(概念)5. IOC操作Bean管理(基于xml方式)5.1 基于xml创建对象5.2 基于xml方式注入属性5.2.1 DI:依赖注入,就是注…...
操作系统 - 第二章
一、进程的定义、组成、组织、特征 一、进程的定义 从不同的角度,进程有不同的定义 1、进程是程序的一次执行过程; 2、进程是一个程序及其数据在处理机上顺序执行时所发生的活动; 3、进程是具有独立功能的程序在数据集合上运行的过程…...
进程控制~
进程控制 (创建、终止,等待,程序替换) 进程创建: pid_t fork();父子进程,数据独有,代码共享,各有各的地址 pit_t vfork();父进程阻塞,直到子进程exit退出或者程序替换之…...
HCIP第一个实验
实验要求与实验拓扑子网划分分析将骨干链路看成一个整体,路由器后的2个环回地址先看成一个,最后再进行拆分。计算得出,一共需要划分为6个子网段,取三位。再将每一条网段,按照题目要求进行划分最后完成子网划分。子网划…...
阿里云轻量服务器--Docker--dubbo-admin安装(连接zookeeper nacos)
前言:当使用dubbo 作为微服务的接口调用,在dubbo 注册到zookeeper 或者nacos 中时 可以安装dubbo-admin 作为服务的监测; 1 Dubbo Admin 介绍: Dubbo 框架提供了丰富的服务治理功能如流量控制、动态配置、服务 Mock、服务测试等…...
树莓派Pico W无线WiFi开发板使用方法及MicroPython编程实践
树莓派Pico W开发板是树莓派基金会于2022年6月底推出的一款无线WiFi开发板,它支持C/C和MicroPython编程。本文介绍树莓派Pico W无线WiFi开发板的使用方法及MicroPython编程示例,包括树莓派Pico W开发板板载LED使用及控制编程示例,Pico W开发板…...
Redis学习【11】之分布式系统
文章目录一 数据分区算法1.1 顺序分区1.1.1 轮询分区算法1.1.2 时间片轮转分区算法1.1.3 数据块分区算法1.1.4 业务主题分区算法1.2 哈希分区1.2.1 节点取模分区算法1.2.2 一致性哈希分区算法1.2.3 虚拟槽分区算法二 分布式系统环境搭建与运行2.1 系统搭建2.1.1 系统架构2.1.2 …...
光速c数列的猜想:光猜
光速c数列的猜想:光猜 2023-03-05 10:26:30 猜测:不同的宇宙光速c并不同 分成等级数列c0,c1,c2,...cn... 地球所处宇宙的真空光速c为c1,其中c0或许假设为光在纯水中速度乎 亦有可能仅有六级对应六道。 宇宙外,容器外也,超过光速c1,为光速c2,可看到容器…...
2023年全国最新交安安全员精选真题及答案12
百分百题库提供交安安全员考试试题、交安安全员考试预测题、交安安全员考试真题、交安安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 21.作业场所监督检查是安全生产监督管理的一种重要形式,作业场所监督…...
2023年全国最新安全员精选真题及答案14
百分百题库提供安全员考试试题、建筑安全员考试预测题、建筑安全员ABC考试真题、安全员证考试题库等,提供在线做题刷题,在线模拟考试,助你考试轻松过关。 81.(单选题)正常工作状态下,高处作业吊篮悬挂机构抗…...
让Vue响应Map或Set的变化操作,在vue中响应map和set数据结构,计算属性的用法,计算属性特点
明确一点 vue的响应式系统不支持Map和Set,也就是说,当Map与Set里面的元素变化时Vue追踪不到这些变化,因此无法做出响应。 如下demo其实是不会进行数据相应的 <h1 v-for"(item,index) in mySetAsList" :key"index"&…...
Unable to find a valid cuDNN algorithm to run convolution
Unable to find a valid cuDNN algorithm to run convolution 今天在复习HumanNerf的时候发现了这个报错, import torch print(torch.cuda.is_available()) 使用上面的代码发现GPU是可以用的,可自己的torch版本对应。 后面继续看帖子,总结有…...
Linux 进程:进程退出返回值的获取
目录一、对输出参数status的理解二、获取进程退出返回值1.位运算(1)异常退出码(2)进程返回值2.宏函数我们常使用函数 wait 和 waitpid 来执行进程等待的功能:处理退出的子进程并释放资源,防止子进程变成僵尸进程。而这两个函数都有一个输出参数status&am…...
JavaScript核心高级内容复习1
本节概述 数据类型的分类和判断 基本(值)类型 Number ----- 任意数值 -------- typeofString ----- 任意字符串 ------ typeofBoolean ---- true/false ----- typeofundefined — undefined ----- typeof/null -------- null ---------- 对象(引用)类型 Object ----- typeof…...
2D图像处理:Qt + Opencv使用光度立体法检测Halcon中提供的缺陷图像
文章目录 不需知道光源方向一、光度立体法(后续有时间在查资料研究)1.1 问题1:Slants和Tilts的理解(暂时是理解的)1.2 问题1:Gradient通道数为1,为何像素点对应的值会有两个?1.3 问题2:F(r,c)=(u(r,c),v(r,c)) 关于高斯曲率和平均曲率如何计算的?二、非标定光源实现光…...
怎样用sql去查一个订单表中一个店铺一段时间的营业收入的环比
一:思路 要查询一个订单表中一个店铺一段时间的营业收入的环比,可以按照以下步骤进行操作: 使用SELECT语句选择需要的数据列,如订单日期和订单金额,以及店铺名称列。 使用WHERE语句过滤出指定店铺和时间段的订单数据…...
SpringSecurity: 默认添加的15个Filter是怎么添加进去的?
总的流程分为两部分,一是先用Map把configurer收集起来,然后再把maper中所有的configurer应用到HttpSecurity对象。 其中的map位于AbstractConfiguredSecurityBuilder这个类。 private final LinkedHashMap<Class<? extends SecurityConfigurer&l…...
学习记录---latent code 潜在编码
文章目录参考文献1. 什么是潜在编码?2.什么是潜在空间?3.同类潜在编码的相似性4.潜在编码的应用4.1 Antoencoders4.2 Generative models5.结论个人学习总结,持续更新中……参考文献 [1] 快速理解深度学习中的latent code潜在编码 1. 什么是…...
Cesium三维数据格式以及生产流程详解(glb,osgb,obj,bim,ifc)等
最近收到私信问我在cesium上展示的一些三维数据是如何生产和处理的,这篇文章就给大家一次性讲个透彻。 首先我们来做做分类。市面上能接触到的,常见的,cesium上支持展示的三维数据大致分为以下几种: 1.倾斜摄影(osgb,obj) 2.点云数据(las,pts) 3.手工模型(gltf,…...
2023年备考信息安全工程师每日知识点(1)
信息安全工程师在软考中属于中级认证,难度尚可,如果从今天开始学的话,肯定来得及 作者简介: 吉林师范大学网络空间安全的一名普通的大一学生已于2022年拿到华为阿里腾讯三家认证吉师信网中心的一名可怜打工人华为MindSpore截至目…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
2025年- H71-Lc179--39.组合总和(回溯,组合)--Java版
1.题目描述 2.思路 当前的元素可以重复使用。 (1)确定回溯算法函数的参数和返回值(一般是void类型) (2)因为是用递归实现的,所以我们要确定终止条件 (3)单层搜索逻辑 二…...
Appium下载安装配置保姆教程(图文详解)
目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...
视觉slam--框架
视觉里程计的框架 传感器 VO--front end VO的缺点 后端--back end 后端对什么数据进行优化 利用什么数据进行优化的 后端是怎么进行优化的 回环检测 建图 建图是指构建地图的过程。 构建的地图是点云地图还是什么信息的地图? 建图并没有一个固定的形式和算法…...
