IOC的原理:
未使用IOC的时候:创建对象的是程序员主动的创建如图
IOC原理实例:
目录:
-
dao层
package com.kuang.dao; public interface UserDao { void getUser(); }
package com.kuang.dao; public class UserDaoImpl implements UserDao { public void getUser() { System.out.println("用户默认的数据"); } }
package com.kuang.dao; public class UserMysqlDaoImpl implements UserDao { public void getUser() { System.out.println("Mysql用户默认的数据"); } }
service层
package com.kuang.service; public interface UserService { void getUserService(); }
我们使用一个Set接口实现,已经发生了革命性的变化
package com.kuang.service; import com.kuang.dao.UserDao; public class UserServiceImpl implements UserService { private UserDao userDao; //利用set进行动态实现值的注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void getUserService() { userDao.getUser(); } }
test层
import com.kuang.dao.UserDaoImpl; import com.kuang.dao.UserMysqlDaoImpl; import com.kuang.service.UserService; import com.kuang.service.UserServiceImpl; public class TestUser { public static void main(String[] args) { //用户实际调用的是业务层,dao层他们不需要接触! UserService service=new UserServiceImpl(); //调用set方法注入对象 ((UserServiceImpl) service).setUserDao(new UserDaoImpl()); service.getUserService(); //调用set方法注入对象 ((UserServiceImpl) service).setUserDao(new UserMysqlDaoImpl()); service.getUserService(); } }
之前,程序是主动创建对象!控制权在程序猿手上!
使用了set注入后,程序不在具有主动性,而是被动的接受对象!
这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注在业务的实现上!这是IOC的原型
使用了IOC原理后,对象不是主动的被创建,而是被动的接收对象!如图
IOC本质
控制反转IOC(Inversion of Control),是一种设计思想,Di(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由成勋自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把二者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection,DI)
使用了SpringIOC容器后,实例如下:
目录:
实体类:
package com.kuang.pojo; public class Student { private String name; private String age; public String getName() { return name; } public String getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(String age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age='" + age + '\'' + '}'; } }
配置文件:
<?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 https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="stu" class="com.kuang.pojo.Student"> <!--使用Spring来创建对象,在Spring这些都称为Bean 类名 变量名 = new 类型(); Student stu= new Student(); id = 变量名 class = new 的对象 property 相当于给对象中的属性设置一个值 --> <!-- ref:引用Spring容器中创建好的对象 value:具体的值,基本数据类型 --> <property name="name" value="sdjhfb"></property> <property name="age" value="18"></property> </bean> </beans>
测试类:
import com.kuang.pojo.Student; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class testStudent { public static void main(String[] args) { //获取Spring上下文对象! ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); //我们的对象现在都在Spring中管理了,我们要使用,直接去里面取就行了 Student student = (Student) ac.getBean("stu"); System.out.println(student); } }
需要的依赖:
<dependencies> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.8</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.8</version> </dependency> </dependencies>
看完这些实例后我们不妨想想几个问题?Student对象是由谁创造的,是由Spring创造的
Student对象的属性是由Spring容器设置的这个过程就叫反转
谁来控制都对象的创建,传统应用程序的对象是由程序本身控制的,使用Spring后,对象是由Spring来创建的
反转:程序本身不创建对象,而变成被动的接收对象
依赖注入:就是利用set方法来进行注入的。
IOC是一种编程思想,由主动的编程变成被动的接收。
可以通过NewClassPathXMLApplicationContext去游览一下底层源码。
总结所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配
通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期
IOC创建对象的方式
1.使用无参构造创建对象,默认!
2.假设我们要使用有参构造创建对象
1、下标赋值
<!-- 1:通过下标的方式来创造对象--> <bean id="stu" class="com.kuang.pojo.Student"> <constructor-arg index="0" value="llj"></constructor-arg> </bean>
2、类型赋值
<!-- 不建议使用 2:通过类型的方式来创造对象 --> <bean id="stu" class="com.kuang.pojo.Student"> <constructor-arg type="java.lang.String" value="李龙杰"></constructor-arg> </bean>
3、名字赋值
<!-- 3:通过name的方式来创造对象--> <bean id="stu" class="com.kuang.pojo.Student"> <constructor-arg name="name" value="李龙浩"></constructor-arg> </bean> <bean id="stuT" class="com.kuang.pojo.StudentT"></bean> </beans>
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!