Spring-IoC(控制反转)
一、 IoC
-
IoC是什么?
IoC(Inverse of Control),即控制反转,是一种程序设计思想。
通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。
-
IoC有什么用?
主要起到程序解耦作用。
以往我们都是以硬编码的方式来完成对象的创建和生命周期管理,代码不灵活、不利于扩展和维护。
而IoC的设计思想是以Spring容器为第三方,由它来管理应用中所有对象的创建和生命周期。
以生活举例,IoC就好比,房东把房子交给中介托管。
二、IoC容器
DI(Dependency Insert),即依赖注入。
IoC容器是具有DI功能的容器。
IoC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
spring提供了以下两种不同类型的容器:
注:以下案例其实都可以用同一个配置文件等,为了清晰各个步骤,我就都重复写了
Spring BeanFactory容器
案例:
1、注入依赖 spring-context
2、创建一个类 MyBeanFactory.class
3、创建配置文件 springioc_bean.xml
4、完善配置文件
5、创建一个测试类 BeanFactoryTest.class
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
创建类
目录结构
创建spring配置文件:
完善配置文件
创建测试类
测试结果
Spring ApplicationContext容器
案例:
1、注入依赖 spring-context
2、创建一个类 MyContext.class
3、创建配置文件 springioc_context.xml
4、完善配置文件
5、创建一个测试类 ContextTest.class
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
创建类
目录结构
创建spring配置文件
完善配置文件
创建测试类
FileSystemXmlApplicationContext:基于文件系统中XML文件配置的应用程序上下文
ClassPathXmlApplicationContext:基于ClassPath路径中XML文件配置的应用程序上下文
测试结果
注:getBean()有两种方式
bean 节点
上例中,配置文件里的bean节点,即spring bean定义,代表一个JavaBean对象。
容器创建bean,需要配置元数据。
bean节点的属性:
属性 | 描述 |
---|---|
class | 这个属性是强制的,指定用来创建bean的bean类的classpath,即包名+类名 |
id | 对象id,id不可重复,指定唯一的bean标识符 |
name | 对象名称,name可以重复,如果重复将读取最后一个 |
scope | 指定bean创建的对象的作用域 ①singleton:单例模式,默认的作用域,Spring 中的缺省作用域,在IoC容器中仅存在一个实例。在创建容器时就同时自动创建了一个 bean 的对象,不管你是否使用,它都存在了,每次获取到的对象都是同一个对象。 ②prototype:多例,每次从IoC容器中调用Bean时,都会返回一个新的实例。在创建容器的时候并没有实例化,而是当获取bean的时候才会去创建一个对象,而且每次获取到的对象都不是同一个对象。 ③request:每次Http请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境 ④session:同一个会话共享一个Bean,不同的会话使用不同的Bean,仅适用于WebApplicationContext环境 ⑤application:一般用于portlet应用环境,仅适用于WebApplicationContext环境 |
constructor-arg | 用来注入依赖关系 |
autowiring mode | 用来注入依赖关系 |
properties | 用来注入依赖关系 |
bean 节点 继承
案例:
1、注入依赖 spring-context
2、创建两个类 Son.class、Parents.class
3、创建配置文件 springioc_beanextends.xml
4、完善配置文件
5、创建一个测试类 BeanExtendsTest.class
pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
创建两个类
目录结构
创建spring配置文件
完善配置文件
创建测试类
测试结果(子定义继承了父定义的属性)
bean 属性注入的几种方式
- 构造函数注入(constructor-arg)
- set方法注入(property)
- 自动装配注入(bean的autowire属性)
类型:
no 默认,不自动装配
byType 通过类型查找对象,如果相同类型的对象有多个,会出现异常
byName 通过名称查找对象,如果找不到对应的id或name的对象,会出现空指针异常
constructor 通过构造方法装配
注解配置IoC
注解 | 描述 |
---|---|
@Component | 组件,被标记的类会被Spring扫描到,交给Spring容器进行管理 |
@ComponentScan | 组件扫描,标记在配置类上,用于扫描某一个包下带 @Component的类 |
@Configuration | 配置类,标记在类上,该类作为配置类代替xml |
@Value | 注入值类型数据,配置属性或set方法上 |
@Autowire | 自动装配,默认按类型进行注入 |
@Qualifier | 标记名称,配置在类和注入属性上,用于区分类型相同的对象。@Autowired 和 @Qualifier 注解可以用来删除混乱。 |
@Resource | 自动装配,类似Autowire,默认按名称注入,名称没有再按类型注入 |
@Repository | 类似@Component,标记DAO实现类 |
@Service | 类似@Component,标记Service实现类 |
@Controller | 类似@Component,标记Controller类 |
案例:
目录结构
给每个接口的一个实现类加上@Component注解
给Computer类添加@Component注解,值类型属性用@Value注入,引用类型用@Autowired注入
这里报错了
因为autowire默认按类型注入,而这里同类型接口的实现类有两个,所以会冲突报错。此时只需要在每个实现类上加上@Qualifier区分即可
配置类
运行结果
IoC实现原理
通过自定义注解+反射机制实现
自定义注解案例:
目录结构
新建两个注解类MyValue、MyComponent