一、概念
IOC:Ioc—Inversion of Control,控制反转。IOC主要是一种设计思想。在应用程序中,原本由程序主动去new依赖对象,变成了由IOC容器来控制对象的创建。所以,所谓的控制反转,控制指的是IOC容器控制了对象的创建,反转指的是程序依赖IOC容器来注入对象。
DI:Dependency Injection,依赖注入。组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。
----------------------------------------------------------------------------------------
谁依赖于谁:当然是应用程序依赖于IoC容器;
为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
摘抄自CSDN: https://blog.csdn.net/qq_22654611/article/details/52606960/
-----------------------------------------------------------------------------------------
明确IOC和DI的关系:其实它们是同一个概念的不同角度描述
一个对象的创建往往会涉及到其他对象的创建,比如一个对象A的成员变量持有着另一个对象B的引用,这就是依赖,A依赖于B。IOC机制既然负责了对象的创建,那么这个依赖关系也就必须由IOC容器负责起来。负责的方式就是DI——依赖注入,通过将依赖关系写入配置文件,然后在创建有依赖关系的对象时,由IOC容器注入依赖的对象,如在创建A时,检查到有依赖关系,IOC容器就把A依赖的对象B创建后注入到A中(组装,通过反射机制实现),然后把A返回给对象请求者,完成工作。
二、实例
1、容器通过配置的xml获取对象:
首先创建一个spring项目,在src目录下创建HelloWorld实体类,代码如下:
public class HelloWorld {
private String hello;
public void setHello(String hello){
this.hello = hello;
}
public void sayHello(){
System.out.println(this.hello);
}
}其次在spring的配置xml(此处我自己在src目录下创建的IOC.xml)文件中,添加bean,代码如下:
其中每个bean的id是其在容器中的标识,class是实体类的具体路径,property配置对象的属性值
<?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="hello" class="HelloWorld"> <property name="hello" value="HelloWorld"></property> </bean> </beans>
之后创建TestIOC ,测试代码如下:
context就是一个IOC容器,它从配置的IOC.xml获取对象资源,并提供给主程序。
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("IOC.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("hello");
helloWorld.sayHello();
}
}2、获取依赖对象:
在原项目src目录下新建Student类,代码如下:
public class Student {
private String name;
public Student(){}
public String getName() { return name; }
public void setName(String name) {this.name = name; }
public void sayName(){
System.out.println(this.getName());
}
}修改HelloWorld,代码如下:
public class HelloWorld {
private String hello;
private Student student;
public HelloWorld(){
}
public void setStudent(Student student){
this.student = student;
}
public Student getStudent() {
return student;
}
public String getHello() {
return hello;
}
public void setHello(String hello){
this.hello = hello;
}
public void sayHello(){
System.out.println(this.hello);
}
}修改IOC.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"> <bean id="student" class="Student"> <property name="name" value="ccc"></property> </bean> <bean id="hello" class="HelloWorld"> <property name="hello" value="helloWorld"></property> <property name="student" ref="student"></property> </bean> </beans>
测试TestIOC:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("IOC.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("hello");
helloWorld.sayHello();
System.out.println(helloWorld.getStudent().getName());
}
}运行结果
信息: Loading XML bean definitions from class path resource [IOC.xml] helloWorld ccc
此时,Student类作为HelloWorld类的依赖对象,所以在创建HelloWorld对象时,IOC容器就把创建Student对象并注入到HelloWorld对象中,就是前面提到的依赖注入。
那么问题来了,如果对于每一个实体类,都要通过配置bean去实现IOC,还相较于直接new来说,开发效率并没有多大的提升,下面提供通过注解的方式去实现实体类的bean配置:
首先开启spring对注解的识别,在IOC.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config></context:annotation-config> <bean id="student" class="Student"> <property name="name" value="ccc"></property> </bean> <bean id="hello" class="HelloWorld"> <property name="hello" value="helloWorld"></property> <!-- <property name="student" ref="student"></property> --> <!--<constructor-arg name="student" ref="student"></constructor-arg> 构造器注入,要求有相应构造函数,参数一致 --> </bean> </beans>
接下来只需要修改HelloWorld,在student属性前添加@Autowired注解,也可以在setStudent方法前添加@Autowired,效果相同,代码如下:
import org.springframework.beans.factory.annotation.Autowired;
public class HelloWorld {
private String hello;
@Autowired
private Student student;
public HelloWorld(){
}
public HelloWorld(Student student) {
this.student = student;
}
public void setStudent(Student student){
this.student = student;
}
public Student getStudent() {
return student;
}
public String getHello() {
return hello;
}
public void setHello(String hello){
this.hello = hello;
}
public void sayHello(){
System.out.println(this.hello);
}
}此外也可以使用@Resource(name=“bean id”)的形式来达到相同的效果,代码如下:
import javax.annotation.Resource;
public class HelloWorld {
private String hello;
@Resource(name="student")
private Student student;
public HelloWorld(){
}
public HelloWorld(Student student) {
this.student = student;
}
public void setStudent(Student student){
this.student = student;
}
public Student getStudent() {
return student;
}
public String getHello() {
return hello;
}
public void setHello(String hello){
this.hello = hello;
}
public void sayHello(){
System.out.println(this.hello);
}
}这样还不够高效,我们还有更简单的实现方法!在IOC.xml下只保留以下代码,意为自动扫描com.IOC.pojo下的类
<context:component-scan base-package="com.IOC.pojo"/>
一开始忘记建包了,emmm,建包com.IOC.pojo 将实体类移入
代码如下:
IOC.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" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.IOC.pojo"></context:component-scan> </beans>
HelloWorld.java: 添加注解@Component("hello"),student属性前@Autowired,然后为hello赋初值
package com.IOC.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component("hello")
public class HelloWorld {
//注意设置初始值
private String hello ="hello";
//@Resource(name="student")
@Autowired
private Student student;
public HelloWorld(){
}
public HelloWorld(Student student) {
this.student = student;
}
public void setStudent(Student student){
this.student = student;
}
public Student getStudent() {
return student;
}
public String getHello() {
return hello;
}
public void setHello(String hello){
this.hello = hello;
}
public void sayHello(){
System.out.println(this.hello);
}
}Student.java: 添加注解@Component("student"),然后为name赋初值
package com.IOC.pojo;
import org.springframework.stereotype.Component;
@Component("student")
public class Student {
//注意设置初值
private String name="ccc";
public Student(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayName(){
System.out.println(this.getName());
}
}TestIoc.java:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.IOC.pojo.*;
public class TestIOC {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("IOC.xml");
HelloWorld helloWorld = (HelloWorld) context.getBean("hello");
helloWorld.sayHello();
System.out.println(helloWorld.getStudent().getName());
}
}以上通过注解实现IOC与配置程序运行结果相同,
共同學習,寫下你的評論
評論加載中...
作者其他優質文章
