IoC控制反转,全称Inverse of Control,是一种设计理念。
由代理人来创建于管理对象,消费者通过代理人来获取对象。
IoC的目的是降低对象之间直接耦合。
加入IoC容器将对象统一管理,让对象关联变为弱耦合。

IoC是设计理念,是现在程序设计遵循的标准,是宏观目标。
DI(Dependency Injection)是具体技术实现,是微观实现。
DI在Java中利用反射技术实现对象注入(Injection)

Spring可以狭义与广义两个角度看待。
狭义的Spring是指Spring框架(Spring Fremework)
广义的Spring是指Spring生态体系。
Spring框架是企业开发复杂性的一站式解决方案。
Spring框架的核心是Ioc容器与AOP面向切面编程。
Spring IoC负责创建于管理系统对象,并在此基础上扩展功能。


对象直接引用导致对象硬性关联,程序难以扩展维护。

IoC容器是Spring生态的地基,用于统一创建于管理对象依赖。

将A对象的依赖B注入到A对象中。
对象的控制权交由第三方统一管理(IoC控制反转)。
利用Java反射技术实现运行时对象创建与关联(DI依赖注入)。
基于配置提高应用程序的可维护性与扩展性。
妈妈在早餐后给三个孩子分发餐后水果
盘子里装有三个苹果:红富士/青苹果/金帅
孩子们口味不同:莉莉喜欢舔的、安迪喜欢酸的、露娜喜欢软的。
孩子如何得到喜欢的苹果?
打开IDEA创建一个maven工程,在com.ql.spring.ioc.entity包下分别创建Apple和Child两个实体类
package com.ql.spring.ioc.entity;
public class Apple {
private String title;
private String color;
private String origin;
public Apple() {
}
public Apple(String title, String color, String origin) {
this.title = title;
this.color = color;
this.origin = origin;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
}
package com.ql.spring.ioc.entity;
public class Child {
private String name;
private Apple apple;
public Child() {
}
public Child(String name, Apple apple) {
this.name = name;
this.apple = apple;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Apple getApple() {
return apple;
}
public void setApple(Apple apple) {
this.apple = apple;
}
public void eat(){
System.out.println(name+"吃到了"+apple.getOrigin()+"种植的"+apple.getTitle());
}
}
然后在com.ql.spring.ioc包下创建Application类
package com.ql.spring.ioc;
import com.ql.spring.ioc.entity.Apple;
import com.ql.spring.ioc.entity.Child;
public class Application {
public static void main(String[] args) {
Apple apple1 = new Apple("红富士","红色","欧洲");
Apple apple2 = new Apple("青苹果","绿色","中亚");
Apple apple3 = new Apple("金帅","黄色","中国");
Child lily = new Child("莉莉", apple1);
Child andy = new Child("安迪", apple2);
Child luna = new Child("露娜", apple3);
lily.eat();
andy.eat();
luna.eat();
}
}
/*
莉莉吃到了欧洲种植的红富士
安迪吃到了中亚种植的青苹果
露娜吃到了中国种植的金帅
*/
以上代码弊端:
1、苹果描述都写死在代码中,苹果信息可能还会产生变化,一旦产生变化,我们就得修改源代码。在真实的环境中,一旦修改源代码,就得重新测试,重新发布,重新上线,甚至需要繁琐的审批流程。所以我们开发的软件得不到及时的反馈和增强。
2、这些对象的数量都是写死的,想新增对象还得修改源代码。
3、这些对象是硬关联,每个孩子和苹果的关系在程序编译的时候就已经确定,这是一件非常死板的事情,如果想要修改关联关系,只能修改源代码。
这些弊端让我们软件的可维护性和可扩展性变得特别差。
引入Spring IoC,打开pom.xml文件,引入Spring依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
</dependencies>
在resources包下创建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">
<!--在IoC容器启动时,自动由Spring实例化Apple对象,取名sweetApple放入到容器中-->
<bean id="sweetApple" class="com.ql.spring.ioc.entity.Apple">
<property name="title" value="红富士"></property>
<property name="origin" value="欧洲"></property>
<property name="color" value="红色"></property>
</bean>
<bean id="sourApple" class="com.ql.spring.ioc.entity.Apple">
<property name="title" value="青苹果"></property>
<property name="origin" value="中亚"></property>
<property name="color" value="绿色"></property>
</bean>
<bean id="softApple" class="com.ql.spring.ioc.entity.Apple">
<property name="title" value="金帅"></property>
<property name="origin" value="中国"></property>
<property name="color" value="黄色"></property>
</bean>
<bean id="rdApple" class="com.ql.spring.ioc.entity.Apple">
<property name="title" value="蛇果"></property>
<property name="origin" value="美国"></property>
<property name="color" value="红色"></property>
</bean>
<bean id="lily" class="com.ql.spring.ioc.entity.Child">
<property name="name" value="莉莉"/>
<property name="apple" ref="sweetApple"/>
</bean>
<bean id="andy" class="com.ql.spring.ioc.entity.Child">
<property name="name" value="安迪"/>
<property name="apple" ref="rdApple"/>
</bean>
<bean id="luna" class="com.ql.spring.ioc.entity.Child">
<property name="name" value="露娜"/>
<property name="apple" ref="softApple"/>
</bean>
</beans>
然后在com.ql.spring.ioc包下创建SpringApplication类
package com.ql.spring.ioc;
import com.ql.spring.ioc.entity.Apple;
import com.ql.spring.ioc.entity.Child;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringApplication {
public static void main(String[] args) {
//创建Spring IoC容器,并根据配置文件在容器中实例化对象
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
Apple sweetApple = context.getBean("sweetApple", Apple.class);
System.out.println(sweetApple.getTitle());
//从IoC容器中提取beanId = lily的对象
Child lily = context.getBean("lily", Child.class);
lily.eat();
Child andy = context.getBean("andy", Child.class);
andy.eat();
Child luna = context.getBean("luna", Child.class);
luna.eat();
}
}
/*
红富士
莉莉吃到了欧洲种植的红富士
安迪吃到了美国种植的蛇果
露娜吃到了中国种植的金帅
*/