Spring IOC 控制反转
一、概述
1、简介
- IOC(Inversion of Control),反转控制
- IOC是个容器
- 把创建对象管理对象的过程交给了Spring框架
2、IOC在Spring中如何实现
- IOC容器中管理的组件叫做bean
- 创建bean之前,首先要创建IOC容器
- ApplicationContext是BeanFactory的子接口,BeanFactory这是IOC容器的基本实现且是Spring内部使用的接口
3、ApplicationContext中的实现类
- ClassPathXmlApplicationContext:通过读取类路径下的XML格式的配置文件创建IOC容器对象 (常用)
- FileFystemXmlApplicationContext:通过文件系统路径读取XML格式的配置文件创建IOC容器对象
- ConfigurableApplicationContext:ApplicationContext的子接口,包含一些扩展方法 refresh() 和 close(),让ApplicationContext 具体启动、关闭和刷新上下文的能力
- WebApplicationContext:专门为Web应用准备,基于Web环境的IOC容器对象,并将对象引入存入ServletContext域中
二、IOC的XML实现方式
1、代码案例
1.1、创建Maven项目
1.2、创建Maven的Module
1.3、导入jar包,配置pom.xml,并下载
<!--配置jar包-->
<dependencies>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.21</version>
</dependency>
<!--junit测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
1.4、创建 com.sgz.ioc 包
1.5、创建DemoIOC类
package com.sgz.ioc;
/**
* 作者:沈公子
* 日期:2022/8/4 - 17:27
* 需求:
*/
public class DemoIOC {
public void FirstIOC(){
System.out.println("我是Spring IOC的XML实现方式");
}
}
1.6、创建applicationContext.xml配置文件
<?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的信息-->
<!--
bean:配置一个bean对象,将对象交过IOC容器管理
id:bean的唯一标识,我们会通过这个获取,可以随意取名,但不能重复
class:类的全路径,找到需要的类
这个配置文件配置后就会直接 new, 底层反射
-->
<bean id="iocOne" class="com.sgz.ioc.DemoIOC"></bean>
</beans>
1.7、创建 com.sgz.test 测试类包
1.8、创建TestIOC测试类
package com.sgz.test;
import com.sgz.ioc.DemoIOC;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 作者:沈公子
* 日期:2022/8/4 - 17:36
* 需求:
*/
public class TestIOC {
@Test
public void testIOC() {
// 1、获取IOC容器,读取配置文件
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2、获取IOC容器中的bean,会得到new对象的地址值
DemoIOC iocOne = (DemoIOC) ioc.getBean("iocOne"); // 通过bean的id获取,这里的 iocOne 是 applicationContext.xml 配置文件中的 id
// 3、调用类中的方法
iocOne.FirstIOC();
}
}
2、获取bean的三种方式
2.1、通过bean的id获取
DemoIOC iocOne = (DemoIOC) ioc.getBean("iocOne"); // 通过bean的id获取
2.2、通过bean的类型获取(接口类也可以,父类也可以)
DemoIOC iocOne = ioc.getBean(DemoIOC.class); // 通过bean的类型获取
2.3、通过bean的id和类型获取
DemoIOC iocOne = ioc.getBean("iocOne", DemoIOC.class); // 通过bean的id和类型获取
2.4、总结
在满足bean的id 唯一性 的前提下,即通过bean的 类型,bean所 继承的类的类型 ,bean所 实现的接口 的类型都可以获取bean
三、IOC的注解实现方式
1、代码案例
1.1、创建Maven项目
1.2、创建Maven的Module
1.3、导入jar包,配置pom.xml,并下载
<!--配置jar包-->
<dependencies>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.21</version>
</dependency>
<!--junit测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
</dependencies>
1.4、创建 com.sgz.ioc 包
1.5、创建DemoIOC类
package com.sgz.ioc;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
/**
* 作者:沈公子
* 日期:2022/8/4 - 18:00
* 需求:
* 四种注解可以完成IOC: @Component、@Controller、@Service、@Repository
* Spring 框架提供的用来完成IOC,设置这些注解后,会被扫描到
* 以 Map -> {K,V}形式,ioc -> {"demoIOC",new DemoIOC()}
*/
//@Component("my") // 自定义bean的名字(对象名),我们就使用这名字就行了,不需要再使用默认的名字
@Component
//@Controller("my")
//@Controller
//@Service("my")
//@Repository("my")
//@Repository
public class DemoIOC {
public void ioc() {
System.out.println("我是 Spring IOC的注解实现方式");
}
}
1.6、创建applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--IOC包扫描-->
<!--
配置包扫描
它会帮我们new对象,DemoIOC demoIOC = new DemoIOC();
会自动生成默认名,一般都是首字母小写(有时候不会),注意看控制台打印提示对象名,也可以通过注解自定义对象名
base-package:指定一个包的路径,它只会扫描类中带有 @Component、@Controller、@Service、@Repository 四者之一注解的
com.sgz.io 扫描该包下加了注解的类
-->
<context:component-scan base-package="com.sgz.ioc"></context:component-scan>
</beans>
1.7、创建 com.sgz.test 测试类包
1.8、创建TestIOC测试类
package com.sgz.test;
import com.sgz.ioc.DemoIOC;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 作者:沈公子
* 日期:2022/8/4 - 17:36
* 需求:
*/
public class TestIOC {
@Test
public void testIOC() {
// 1、读取配置文件
ClassPathXmlApplicationContext spring = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2、直接getBean
DemoIOC demoIOC = (DemoIOC) spring.getBean("demoIOC"); // 使用默认名,默认值为类的驼峰,即类名的首字母为小写
// DemoIOC demoIOC = (DemoIOC) spring.getBean("my"); // 使用自定义
// 3、调用该类的方法
demoIOC.ioc();
}
}
2、IOC的四种注解
2.1、四个注解
- @Component:将类标识为普通组件
- @Controller:将类标识为控制层组件
- @Service:将类标识为业务层组件
- @Repository:将类标识为持久层组件
2.2、注意
- 它们本质上一样,但是为了代码的可读性,不能随便标记
- 默认值为类的驼峰,即类名的首字母为小写
- 可以通过标识组件的注解的value属性值设置bean的自定义的id
- 例:@Component(“my”)
- 实现扫描组件必须设置四个注解其中之一,否则扫描不到
3、IOC的扫描
3.1、扫描组件
- context:component-scan:扫描组件
- base-package:需要扫描组件的包,会扫描该包下的所有内容
- 生成bean的id,为类名首字母为小写
<context:component-scan base-package="com.sgz.ioc"></context:component-scan>
3.2、排除扫描
<context:component-scan base-package="com.sgz.ioc" >
<!--排除扫描-->
<!-- assignable 根据类型,类的全类名-->
<context:exclude-filter type="assignable" expression="com.sgz.ioc.controller.UserController"/>
</context:component-scan>
3.3、包含扫描
<context:component-scan base-package="com.sgz.ioc" use-default-filters="false">
<!--根据注解-->
<!--包含扫描,需要再ontext:component-scan中设置
use-default-filters="false":所设置的包下所有的类都不需要扫描,此时可以使用包含扫描
use-default-filters="ture":默认的,所设置的包下所有的类型都需要扫描,此时可以使用排除扫描-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>