1 应用背景
IOC(Inversion of Control)控制反转,是面向对象编程中的一种设计原则,可以用来降低不同对象代码间的耦合度,最常见的方式是依赖注入。
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递。
目的:耦合度降低最低限度
2 实现原理
2.1 IOC的过程
IOC的过程xml解析、工厂模式、反射,进一步降低耦合度,后续只需要通过配置的方式进行修改
- xml配置文件,配置创建的对象
< bean id=“dao” class=“com.atwb.UserDao”></ bean> - 有service类和dao类,创建工厂类
class UserFactory { public static UserDao getDao() { String classValue = class属性值; // xml解析 Class clazz = Class.forName(classValue); // 通过反射创建对象 return (UserDao)clazz.newInstance(); } } ```
2.2 IOC容器
IOC思想基于IOC容器完成,IOC容器底层就是对象工厂
Spring提供IOC容器实现有两种方式
- BeanFactory:IOC容器基本实现,是Spring内部使用接口,不提供开发人员进行使用,加载配置文件时不会创建对象,只会加载配置文件,只有在获取对象时才去创建
- ApplicationContext:BeanFactory子接口,一般由开发人员进行使用,在加载配置文件时就会把配置文件的对象进行创建
创建对象的过程比较耗时,使用第二种方法,可以把这个耗时的过程放在服务器启动阶段去完成。
3 基于xml的Bean管理
包括对象创建和注入属性两部分
3.1 基于xml方式创建对象
- 在spring配置文件中,使用bean标签并添加对应属性就可以实现对象创建
- 常用属性
id:唯一标识
class:包类路径
name:可以包含特殊字符的id,不常用 - 创建对象是,默认会执行无参数的构造方法
3.2 基于xml方式注入属性
1 使用set方法进行注入
在bean类中设置好set方法
在spring配置文件中使用
< property name=“bookName” value=“狂人日记”></ property>
2 使用有参构造注入属性
在bean类中设置好有参构造函数
<constrcutor-arg name = “bookName” value = "狂人日记”></ constructor-arg> 通过名称进行属性注入
<constrcutor-arg index = “0” value = "狂人日记”></ constructor-arg> 通过属性索引序号进行注入
3 注入字面量的特殊情况
null值:
< property name=“bookName” >
< null/>
</ property>
特殊符号:
方式1:转义
方式2:把特殊符号写到CDATA中 <<南京>>是要输出的内容
< property name=“bookName” >
< value><![CDATA[<<南京>>]]</ value>
</ property>
4 注入属性-外部bean
在service类对象中注入Dao类对象的属性
< bean id=“service” class=“com.atwb.Service”>
< property name=“bookName” ref=“DaoImpl”></ property>
</ bean>
< bean id=“dao” class=“com.atwb.DaoImpl”></ bean>
5 注入属性-内部bean
内部bean不过是把外部bean放到了 内部 类似这种
< bean id=“service” class=“com.atwb.Service”>
< property name=“bookName”>
< bean id=“dao” class=“com.atwb.DaoImpl”> </ bean>
</ property>
</ bean>
6 注入属性-级联赋值
可以像5中后面描述的外部赋值
或者像4中使用dao.name这种方式
什么外部、内部、级联,其实都是一种写法
7 注入集合类型属性
数组、list、Set、Map
Map
< property name="maps">
<map>
< entry key="JAVA" value="java"></ entry>
</map>
</property>
< property name="lists">
<list>
<value>MySQL</value>
</list>
</property>
8 在集合注入部分提取出来
(1)在spring配置文件中引入名称空间util
(2)使用util标签完成list集合注入提取
<util:list id = "bookList">
<value>测试1</value>
<value>测试2</value>
</util:list>
3.3 工厂Bean
Spring有两种类型的bean,一种是自己创建的普通bean,另一种是工厂Bean
- 普通bean,在配置文件中定义bean类型就是返回类型
- 工厂bean:在配置文件定义bean类型可以和返回类型不一样
工厂bean使用方法:
第一步 创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步 实现接口里面的方法,在实现的方法中定义返回的bean类型
3.4 Bean作用域
- 单实例,即每次创建的都是一个对象;
多实例,每次创建对象是不同的 - 在spring配置文件bean标签里有属性(scope)用于设置单实例还是多实例
- scope属性值
第一个值 默认值 singleton,表示是单实例对象,加载spring配置文件时候就会创建单实例对象
第二个值 prototype,表示是多实例对象,在调用getBean方法的时候创建对象
其实还有request 和 session可选,分别表示把对象设置到request和session中
3.5 Bean生命周期
从对象创建到销毁的过程叫生命周期,其中涉及的步骤
(1)通过构造器创建bean实例(无参数构造)
(2)为bean的属性设置值和对其他bean引用(调用set方法)
(3)把bean实例传递bean后置处理器的方法
(4)调用bean的初始化的方法(需要进行配置初始化的方法)
(5)把bean实例传递bean后置处理器的方法
(4)bean可以使用了(对象获取到了)
(5)容器关闭时,调用bean销毁的方法(需要进行配置销毁的方法)
初始化和销毁的方法在< bean>中分别通过init-method 和 destroy-method 进行配置
后置处理器如何配置?
- 创建类A,实现接口BeanPostProcessor,创建后置处理器,该接口中分别有两个方法会在初始化前后执行
- 在配置文件中进行配置:直接在配置文件中使用< bean> 创建A的对象,为配置文件中所有对象添加实现的后置处理器
3.6 xml自动装配(用的很少,多用注解)
上面介绍的属性注入都是手动装配的过程,根据指定指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入
bean标签属性autowire,配置自动装配
autowire属性常用的两个值:
① byName:bean的id值和类属性名称一样
② byType:根据属性类型自动注入,要保证属性类型唯一
3.7 Bean管理的外部属性文件
- 应用场景:手动属性注入时,有些固定值可以放到properties外部文件中(比如数据库的地址,账号,密码)在xml文件中通过读取这一外部文件内容实现注入过程
- 举例 - 引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties格式文件,写数据库信息
(2)把外部properties属性文件引入到spring配置文件中
① 引入context名称空间 xmlns:context
② 在spring中引入外部属性文件
4 Bean管理(基于注解方式)
4.1 什么是注解
(1)注解是代码特殊标记,格式:@注解名称(属性名称=属性值)
(2)使用注解,注解作用在类上面,方法上面,属性上面
(3)使用注解目的:简化xml配置
4.2 Spring针对Bean管理中创建对象提供的注解
(1)@Component,普通
(2)@Service,建议用在Service层
(3)@Controller,建议用在Web层
(4)@Repository,建议用在DO层
这四个注解功能是一样的,都可以用来创建bean实例
4.3 基于注解方式实现对象的创建
第一步 引入依赖,除了最基本的还有spring-aop
第二步 开启组件扫描(package维度)告诉spring去哪里寻找注解
在配置文件中引入context名称空间,然后在配置文件中开启
第三步 创建类,在类上面添加创建对象注解
默认值是首字母小写的类名称
4.4 开启组件扫描中的一些细节问题
哪些扫描,哪些不扫描是可以进行配置的
include,只扫描设置的
exclude,扫描中排除设置的
4.5 基于注解方式实现属性注入
(1)@AutoWired:根据属性类型进行自动装配
(2)@Qualifier:根据属性名称进行注入
这个要和上面的@Autowired一起使用,比如一个接口有多个实现类,按照接口类型进行注入无法判断具体使用哪个,所以要指定名称
(3)@Resource:可以根据类型注入,也可以根据名称注入
(4)@Value:注入普通类型属性
4.6 完全注解开发
(1)创建配置类,替代xml配置文件
这部分SpringBoot有更简化的方法,但本质是一样的