目录
3.为了更进一步降低类之间的耦合度,同时不使用new创建对象,我们引入IOC容器
前言
IOC是Spring框架提供的一种容器,用于控制对象的创建和对象之间的调用
一、IOC概念
IOC中文翻译为控制的反转。通过IOC容器,把对象的创建和调用过程交给Spring进行管理,省去了使用 "new 类名" 的方式创建对象。
二、IOC原理和示例演示
讲解原理之前,我们先引入几个示例,了解为什么需要用IOC,以及IOC创建对象和传统创建对象的区别
1.传统创建对象和调用对象
//用户类
public class User{
//用户类的method1方法
public void method1(){
System.out.println("用户信息……")
}
}
//管理员类
public class Admin{
//创建User对象
User user = new User()
public static void main(String[] args){
//管理员调取用户的method1方法
user.method1()
}
}
2.在传统基础上添加一个工厂类,可以降低两个类之间的耦合度
//用户类
publiv class User{
//用户类的method1方法
public void method1(){
System.out.println("用户信息……")
}
}
//管理员类
publiv class Admin{
//创建User对象
User user = new User()
public static void main(String[] args){
//管理员调取用户的method1方法
user.method1()
}
}
//工厂类
public class Factory{
//工厂类的method2方法,用于返回用户类对象
public static User method2(){
return new User();
}
}
*可以看出,加入工厂类之后,虽然略微降低了User类和Admin类之间的耦合度,但本质上还是由工厂类 new User 对象,然后返回给Admin类,本质是不变的,耦合度也还是很高
3.为了更进一步降低类之间的耦合度,同时不使用new创建对象,我们引入IOC容器
继续引用上面的示例我们展示IOC容器创建和调用对象的过程(此过程其实就是IOC容器的原理)
IOC过程
第一步: 创建xml配置文件,配置创建对象
<bean id="user" class="com.demo"></bean>
第二步:创建工厂类(为什么会有工厂类,我们后面会讲,不要急)
//工厂类
public class Factory{
//工厂类的method2方法
public static User method2(){
//1.通过xml解析可以得到xml文件中的class值,也就是需要创建对象的类的路径
String classValue = class属性值
//2.通过反射可以得到类的字节码文件,从而创建对象
Class class1 = Class.forName(classValue) //2.1通过反射获取类的字节码文件
return (User)class1.newInstance() //2.2通过字节码文件创建类的对象
}
}
由此,通过IOC创建对象的过程就完成了。相信小伙伴看到这里有点懵懵的感觉,下面我来解答几个疑惑点
1. xml,工厂类,反射
xml解析,工厂模式和反射是IOC容器的三个主要组成部分
2.xml文件内容的含义
<bean></bean>是xml文件中的一种标签,标签内可以设置 id,class等。
class:需要创建对象的类所属的位置,也就是类的路径
id:bean标签名称
3.Factory工厂类内容的含义
String classValue = class属性值 //先通过xml解析的方法将 "class属性值"(类的路径)
Class class1 = Class.forName(classValue) //然后通过反射获取类的字节码文件
return (User)class1.newInstance() //最后通过获取的字节码文件创建类的对象,并将其强转为User类型,并返回
*看到这里,或许小伙伴已经不那么蒙圈了,但是有的小伙伴可能要问了:这个过程这么麻烦,我还不如原来的方法简单,容易理解。别急,上面的是IOC容器创建对象底层原理,实际操作中我们是不需要自己写的,通过IOC提供的两个接口,直接引用就可以了。
4.IOC容器提供的两个接口
上面提到IOC主要由xml解析,工厂模式和反射三个部分组成。而工厂其实是创建对象最重要的部分,所以,IOC底层就是对象工厂,而工厂的方法需要提供接口进行实现,Spring为IOC容器的实现提供了两个接口
接口1 BeanFactory
public class TestDemo {
@Test
public void test(){
//1.加载配置文件
BeanFactory beanFactory=
new ClassPathXmlApplicationContext("User.xml");
//2.获取IOC容器创建的对象
User user = beanFactory.getBean("user", User.class);
//3.调用user的method1方法
user.method1();
}
}
接口2 ApplicationContext
public class TestDemo {
@Test
public void test(){
//1.加载配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("User.xml");
//2.获取IOC容器创建的对象
User user = context.getBean("user", User.class);
//3.调用user的method1方法
user.method1();
}
}
1.加载配置文件
BeanFactory beanFactory=
new ClassPathXmlApplicationContext("User.xml");//" ClassPathXmlApplicationContext("User.xml") " 是BeanFactory接口的实现类,这里使用了多态的构造方法。" ("User.xml") " 指的是创建对象所需要的配置文件名称
2.获得IOC容器创造的对象
User user = context.getBean("user", User.class);
//" context.getBean" 是BeanFactory接口提供的方法,用于获取IOC容器创造的对象,也就是用于接收工厂类中返回的对象
//" ("user", User.class) " 里面分别是xml文件的 " id ",对象的类型(一般是对象的类名)
3.两种接口的异同
同:①两种接口都可以实现对象的获取
异:①BeanFactory通常是Spring内部使用的接口,一般不提供开发人员使用; ApplicationContext是BeanFactory接口的子接口,具有更强大的功能,通常提供开发人员使用
②使用BeanFactory时,在加载配置文件的时候,不会创建对象;在获取对象时,才会创建对象;
使用ApplicationContext时,在加载配置文件的时候就会创建对象
推荐:一般采用第二种方式ApplicationContext更合适,因为使用Spring框架一般结合Web项目,即需要启动tomact服务器,这种耗时,耗资源的操作都在启动项目的时候处理更合适。
5.使用IOC容器创建对象完整演示
-
步骤1
创建Admin和User两个类
//用户类
publiv class User{
//用户类的method1方法
public void method1(){
System.out.println("用户信息……")
}
}
//管理员类
public class Admin{
}
-
步骤2
创建User.xml配置文件
//以上部分时IDEA编译器自动生成的,同志们不用担心
<?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="user" class="com.Demo"></bean>
-
步骤3
在Admin类中实例化ApplicationContext接口,获取user对象,调用user的method1方法
public class Admin {
public static void main(String[] args){
//1.加载配置文件
ApplicationContext context=
new ClassPathXmlApplicationContext("User.xml");
//2.获取IOC容器创建的对象
User user = context.getBean("user", User.class);
//3.调用user的method1方法
user.method1();
}
}
-
步骤4
在Admin类中运行,结果如下
总结
以上就是今天要讲的内容,本文仅仅简单介绍了我对于IOC容器的底层原理,主要组成部分和入门使用方法的理解。在实际开发和应用中,IOC容器还有更深,更广的用法和含义。星光不问赶路人 时光不负有心人,跳动的代码是冷漠的,但跳动的心是炽热的。