Spring之IOC容器
目录
目录
一.IOC容器的介绍
二.传统程序开发 VS IOC容器
2.1传统方法
2.2 改进方法(解耦)
2.3 IOC容器的理解
3.IOC的实现方式
3.1配置文件
本文目的:清楚IOC到底是什么,从代码角度和实际生活中更加深层次了解。
一.IOC容器的介绍
IOC(Inversion of Control)容器是 Spring 框架的核心之一,也是其最为重要的特性之一。IOC 容器是一个用于管理对象生命周期和对象之间关系的容器,它实现了控制反转(IoC),即将应用程序的控制权交给容器,由容器来创建、管理、配置对象之间的依赖关系。
ioc不同于传统程序开发,主要目的:降低程序的耦合关系
二.传统程序开发 VS IOC容器
2.1传统方法
从上往下设计,我们通常先创建大体,再创建细节。例如:
初始化汽车:
class NewCar{
public static void main(String[] args) {
Car car = new Car();
car.init();
}
}
汽车依赖于车身,因此需要初始化车身
class Car{
public static void main(String[] args) {
Framework framework = new Framework();
framework.init();
}
}
车身依赖于底盘,因此需要初始化底盘
class Bottom{
public static void main(String[] args) {
Bottom bottom = new Bottom();
bottom.init();
}
}
底盘依赖于轮胎,因此需要初始化轮胎
class Bottom {
public void init() {
Tire tire = new Tire();
tire.init();
}
}
轮胎初始化:
class Tire {
private int size = 30; //轮胎默认大小
*/public Tire(int size) {
* this.size = size; 该构造函数是后续讲的缺陷之处
*}
*/
public void init() {
System.out.println("轮胎尺⼨:" + size);
}
}
从代码上看,我们可以发现这种耦合度太高了,为什么这么说呢?你想啊,如果我在轮胎类中添加一个构造函数,代表new的时候,获取轮胎大小!那么你会发现整个程序都要修改!
问题:当最底层代码改动之后,整个调⽤链上的所有代码都需要修改
那么如何解决这种缺陷呢? 答:使用注入方法
2.2 改进方法(解耦)
在讲解IOC容器之前,我先讲解一下什么是注入方法!
所谓的注入方法,例如:将汽车建造分为4个步骤,
- 将车轮胎做好,上交给底盘制造者
- 底盘制造者根据轮胎大小制造出底盘,上交给车身制造者
- 车身制造者根据底盘大小制造出车身,并组合成汽车
代码改进:
public class NewCar {
public static void main(String[] args) {
Tire tire = new Tire(20); //制造出轮胎
Bottom bottom = new Bottom(tire); //交与底盘制造者
Framework framework = new Framework(bottom); //交于车身制造者
Car car = new Car(framework);
car.run();
}
}
代码经过以上调整,⽆论底层类如何变化,整个调⽤链是不⽤做任何改变的,这样就完成了代码之间的解耦,从⽽实现了更加灵活、通⽤的程序设计了
2.3 IOC容器的理解
ioc容器具有两个最为基本的功能:
- 将对象存入容器
- 从容器中去除对象
在上述的改进方法中,我们可以发现,使用的方法是注入,这也是一样的道理,只不过不是注入给其他对象,而是注入到一个公共容器,当你需要的时候,自取便可 。
结论:Spring 是⼀个 IoC 容器,说的是对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒。而我们主要学习如何从spring当中取出我们需要的对象!
3.IOC的实现方式
IOC 容器主要有两种实现方式:
- BeanFactory: BeanFactory 是 Spring 框架最基本的 IOC 容器,它提供了最简单的 IOC 容器功能,适用于大多数情况。BeanFactory 使用延迟初始化机制,只有在首次请求时才会创建对象。
- ApplicationContext: ApplicationContext 是 BeanFactory 的扩展,提供了更多的企业级功能和特性。ApplicationContext 在容器启动时就会实例化所有的对象,并对其进行初始化,因此在性能上相对于 BeanFactory 有所提升。
第一种方式实现代码:
1.Java类-便于Spring管理的Bean
public class MyBean {
public MyBean() {
System.out.println("MyBean 实例化了!");
}
public void doSomething() {
System.out.println("MyBean 执行了某些操作!");
}
}
2.xml配置 lazy-init:设置 Bean 的延迟初始化属性为 true,表示在需要时才实例化该 Bean。
<?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">
// 将扫描的类以"myBean"名放入Spring容器中
<bean id="myBean" class="com.example.MyBean" lazy-init="true"/>
</beans>
3.BeanFactory方法:从容器中取出此类
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class Main {
public static void main(String[] args) {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
System.out.println("容器初始化完成!");
// 在首次请求时才会创建对象 从容器中找到id为myBean的对象
MyBean myBean = (MyBean) beanFactory.getBean("myBean");
myBean.doSomething();
}
}
第二种方式实现代码
1.Java类-便于Spring管理的Bean和上述一样
2.xml配置 和上述一样
3.使用ApplicationContext,代码如下:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
System.out.println("容器初始化完成!");
// 容器启动时就会实例化所有的对象
MyBean myBean = (MyBean) context.getBean("myBean");
myBean.doSomething();
}
}
这便是获取Spring中bean对象的方式,当然除了以上方法,还有其他获取Bean对象,但还可以更加简便获取Bean对象。——使用添加注解和@Autowired存储 Bean 对象。
注:bean 使⽤的都是标准的⼤驼峰命名,也就是说xml文件里的Bean的id的是Java类的小驼峰
3.1配置文件
通过配置文件(如 XML 配置文件)或注解,开发者可以告诉 IOC 容器如何创建对象、管理对象之间的依赖关系,使得应用程序的组件更加松散耦合、更易于维护和测试。
例如:
base-package扫描的是需要注入的文件目录
总结: IOC 容器是 Spring 框架的核心机制之一,通过实现控制反转,帮助开发者简化了对象的管理和依赖注入,提高了代码的灵活性和可维护性。
还没有评论,来说两句吧...