- IOC:
Inversion of control
控制反转- DI:
dependence injection
依赖注入
以上两个词是一个意思,只是站在不同的角度去描述同一件事情
那么,为什么说 是“依赖注入、控制反转”呢?
之前是程序员 主动维护 对象的创建
现在程序员把对象创建的权力交给了spring框架
spring框架 拥有了 对象创建的权力
程序员 失去了 对象创建的权力
对象创建的权力发生了反转,因此就被称为控制反转
通俗一点地讲:
因为 我们设置的对象,不是由我们去创建,去new,
而是通过Spring的IoC/DI机制,进行自动注入
因此,我们称之为“依赖注入”
而 现在控制对象创建工作的,不是程序员,而是程序
因此,我们称之为“控制反转”
那么,为什么程序员 不new,而要让容器 进行 对象的注入呢?
答曰:
程序员主动去new,会导致如下几个缺点:
- 扩展性差
- 维护性差
- 每一层的依赖严重
servlet层 依赖 对象的创建
service层 依赖 dao对象的创建
例如:
钱在你的口袋,钱的控制权在自己(相当于 new),
钱在银行,钱的控制权在银行(相当于 控制反转)
那么,当我们需要进行 转账、利息 等功能操作时,
就不用 来回跑、找办法 涨利息了
那么,现在本人就来讲解下IoC/DI机制的语法:
- 在Maven中添加相关依赖
- 在resources包下,创建名为applicationContext.xml的核心配置文件
- 书写 配置文件的内容
- 在需要的类中通过ApplicationContext接口的实现类的getBean()方法,
以配置文件中的id为索引,获取指定的对象
那么,接下来,本人就来具体说明下每一步的细节吧:
首先,我们需要在Maven中添加如下依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
其次,我们需要在resources包下,
创建名为applicationContext.xml的核心配置文件
本人现在来对这个配置文件做下说明:
说明:
spring的核心配置文件
也是spring容器配置文件,
在此文件中目前主要配置Javabean,
配置Javabean就是将 Javabean 交给 spring容器 进行管理
配置文件 书写格式:
基本骨架:
<bean id="" class="">
</bean>
那么,本人对上述的两个属性做下解释:
解释:
- id :
是spring容器中bean的唯一标识
在程序中可以通过id 获取bean对象- class:
填写属性的值必须是类的全路径,以便底层反射机制的执行
此刻的类必须严格遵守Javabean的规范,也就是需要有一个无参数的构造方法
我们可以在上述格式中增加子级标签和属性,来完善配置文件
那么,我们向配置文件中存储了数据,该如何读取呢?
答曰:
可以通过ApplicationContext接口的实现类的getBean()方法,
以配置文件中的id为索引,获取指定的对象
现在,本人来展示下如何通过配置文件来获取指定的对象:
例子:
本人先来给出一个之后要被注入的 SimpleClass类:
package edu.youzg.about_Spring.core;
public class SimpleClass {
public SimpleClass() {
}
public void doSomething() {
System.out.println("Hello spring framework!");
}
}
接下来,本人根据这个类的信息,来给出配置文件的信息:
<?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="simpleClass" class="edu.youzg.about_Spring.core.SimpleClass" />
</beans>
现在,本人来给出一个测试类:
package edu.youzg.about_Spring.core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Demo {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SimpleClass simpleClass = context.getBean("simpleClass", SimpleClass.class);
simpleClass.doSomething();
}
}
那么,现在,本人来展示下运行结果:
可以看到:我们并没有去new对象,却能够调用该类的非静态方法,
这就表明,我们通过配置文件,对对象的注入工作,成功了!
其实 spring容器方法是 由Beanfactory接口提供了最基础的spring容器方法。
上述的使用过程中,能看到我们使用了ApplicationContext接口的实现类,
实现了对象的注入工作
这是因为,ApplicationContext接口是Beanfactory接口的子接口:
那么,现在,本人来对上述的语法进行下解释:
spring框架提供的进行注入操作Java接口只有一个 —— ApplicationContext接口
那么,这个接口,有四个实现类
首先是 applicationContext.xml(核心配置文件):
<bean id="该对象的id" class="指定的类" scope="作用域">
</bean>
那么,本人对上文中的作用域做下说明:
作用域 取值:
- singleton:默认值,所注入的对象都是单例的(即:同一个对象)
- proptotype:原型模式(相当于new),每次都是新的对象
- request
- session
- application
- websocket
例如:
<bean id="simpleClass" class="edu.youzg.about_Spring.core.SimpleClass" scope="singleton">
</bean>
<bean id="该对象的id" class="指定的类" factory-method="静态工厂所提供的类的创建方法">
</bean>
例如:
<!--将jdk 中 java.lang.Runtime类交给spring容器-->
<!--私有构造方法保证了类在外部不能访问,注意spring中为了编写代码的方便,破坏了java的封装性,可以在类的外部访问私有属性-->
<!--通过工厂方法创建对象的方式,用的不是很多,存在的意义是如果我们使用第三方提供的类,没办法修改他人的代码-->
<bean id="runtime" class="java.lang.Runtime" factory-method="getRuntime" />
<!--spring创建javabean的第三种方式使用实例方法创建-->
<bean id="工厂类的id" class="edu.youzg.about_spring.core.UserFactory" />
<!--指定工厂类userFactory,指定工厂方法getUS-->
<bean id="目标对象的id" factory-method="工厂类提供的工厂方法" factory-bean="工厂类的id" />
而读取该配置文件,创建并注入所需对象 的操作,都是按照如下的模板:
/* 获取ClassPathXmlApplicationContext对象 */
//以便我们之后通过这个对象进行 指定类的对象的注入
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
/* 获取指定类对象 的方式有两种 */
//格式1:
指定类 要被注入的对象 = context.getBean("配置文件中存储的id", 指定类.class);
//格式2:
指定类 要被注入的对象 = (指定类)context.getBean("配置文件中存储的id");
其实上述的格式,也不是很完善,
因为 一个程序会有多个类组成,
类于类之间会相互调用,
比如service类会调用dao类的对象
那么,在我们之前的学习中,能够知道:
类的成员变量,一般有两种注入方式:
- 使用setter方法对成员对象进行 注入
- 使用构造方法对成员对象进行 注入
那么,接下来,本人就来讲解下:
spring框架如何通过 这两种方式,来对成员对象进行注入:
格式:
<!--将参与依赖的bean对象交给spring容器-->
<bean id="成员对象类 的编号" class="成员对象类 的全路径名" />
<!--service中引用了userdao对象-->
<bean id="目标类" class="目标类 的全路径名" >
<!--容器开始为目标类类的 成员属性 设置/注入 实现对象了-->
<!--这就是依赖注入-->
<property name="成员名称" ref="成员对象类 的编号" />
</bean>
(注意:成员名称一定要保证和目标类中setter方法的后缀名称一致,
以便我们反射机制的调用)
例子:
本人先来给出一个 将被注入依赖的类 —— SimpleClass类:
package edu.youzg.about_Spring.core;
/**
* @Author: Youzg
* @CreateTime: 2020-04-24 14:17
* @Description:带你深究Java的本质!
*/
public class SimpleClass {
private SimpleTwo simpleTwo;
private SimpleThree simpleThree;
public void setSimTwo(SimpleTwo simpleTwo) {
this.simpleTwo = simpleTwo;
}
public void setSimpThree(SimpleThree simpleThree) {
this.simpleThree = simpleThree;
}
public void doSomething() {
System.out.println("Hello spring framework!");
}
}
相应地,本人来给出配置文件:
<?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="simpleTwo" class="edu.youzg.about_Spring.core.SimpleTwo" />
<bean id="simpleThree" class="edu.youzg.about_Spring.core.SimpleThree"/>
<bean id="simpleClass" class="edu.youzg.about_Spring.core.SimpleClass">
<property name="simpThree" ref="simpleThree" />
<property name="simTwo" ref="simpleTwo"/>
</bean>
</beans>
那么,现在本人来给出一个测试类:
package edu.youzg.about_Spring.core;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author: Youzg
* @CreateTime: 2020-04-22 23:05
* @PROJECT: SpringStudy
* @PACKAGE: edu.youzg.about_Spring
* @Description:
*/
public class Demo {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
SimpleClass simpleClass = (SimpleClass) context.getBean("simpleClass");
simpleClass.doSomething();
}
}
现在,本人来展示下运行结果:
<bean id="userDao" class="com.lux.dao.UserDao" />
<bean id="userDaoOracle" class="com.lux.dao.UserDaoOracle" />
<!--service中引用了userdao对象-->
<!--javabean编写了有参数的构造方法,无参数的构造方法被覆盖,spring容器无法通过默认方式(无参数构造方法)创建javabean对象-->
<bean id="userService" class="com.lux.service.UserService" >
<!--构造方法注入-->
<constructor-arg ref="userDaoOracle" />
</bean>
例子:
本人先来给出一个将被注入依赖的类 —— SimpleClass类:
package edu.youzg.about_Spring.core;
/**
* @Author: Youzg
* @CreateTime: 2020-04-24 14:17
* @Description:带你深究Java的本质!
*/
public class SimpleClass {
private SimpleTwo simpleTwo;
public SimpleClass(SimpleTwo simpleTwo) {
this.simpleTwo = simpleTwo;
}
public void doSomething() {
System.out.println("Hello spring framework!");
}
}
那么,相应地,本人来给出 配置文件内容:
<?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="simpleTwo" class="edu.youzg.about_Spring.core.SimpleTwo" />
<bean id="simpleThree" class="edu.youzg.about_Spring.core.SimpleThree"/>
<bean id="simpleClass" class="edu.youzg.about_Spring.core.SimpleClass">
<constructor-arg ref="simpleThree"></constructor-arg>
<constructor-arg ref="simpleTwo"></constructor-arg>
</bean>
</beans>
至于测试类,和上面的例子一样,不需要改变
那么,现在本人来展示下运行结果:
原文:https://www.cnblogs.com/codderYouzg/p/12767402.html