在Spring中对IoC的理解

IoC的定义

  IoC控制反转(baiInversion of Control,英文缩写为IoC),把创建对象的权利交给框架,是框架的重要特征,IoC不是一种技术,而是一种设计思想,并非面向对象编程的专用术语。它包括依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。
  传统的创建对象方式是通过关键字new进行创建,IoC的思想是通过Spring容器来创建对象,由容器来控制对象。
  何为正转,何为反转?传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象,当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了。为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了

IoC能做什么?

  IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出低耦合、高优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

IoC和DI

  DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
  理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

  • 谁依赖于谁:当然是应用程序依赖于IoC容器;
  • 为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
  • 谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
  • 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。

  IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

依赖注入的几种方式

  这里举几个SpringBoot应用IoC思想的几个例子,Springboot会自动加载resources文件下面的application.yml或者application.properties配置文件,因为yml格式可以替代xml格式,功能properties更强大,所以一般都使用yml格式进行书写。

1.对于yml中定义了的bean,可以使用 @value("${对象}") 进行注入。 如果是对象变量,可以直接在变量上使用value注解进行注入。如果是下图这样的静态变量,就需要在set方法上使用value注解。注意:必须是在Spring容器中的对象才能够进行注入,即需要加@Component注解。

student: 
	name: 小明
	age: 15
@Component
public class Student {
    public static String name;
    public static int age;
 
    @Value("${student.name}")
    public void setName(String name){
        Student.name = name;
    }
 
    @Value("${student.age}")
    public void setAge(int age){
        Student.age = age;
    }
}

2.也可以在需要使用Spring容器值的类上加
@Component和@ConfigurationProperties(prefix=“对象名”),将application.yml中配置的对象student(IOC容器中的值)注入进来。(必须是IoC容器中的对象,才能够被注入值,即必须被声明为@Component注解)。

student: 
	name: 小明
	age: 15
@Component
@ConfigurationProperties(prefix = "student")
public class Student {
    public static String name;
    public static int age;
 
    public void setName(String name){
        this.name = name;
    }
 
    public void setAge(int age){
        this.age = age;
    }
}

3.可以使用@Configuration、@PropertySource(value=“classpath:test.properties”)、@ConfigurationProperties(prefix=“student”)这三个注解将resources文件下test.properties描述的student对象的属性注入到student对象中(即使用自定义的配置文件,将属性注入到对象中)。 @Configuration注解可以替换为@Component注解,@Configuration注解其实继承了@Component注解,用来表示该类是配置类。

student.name = '小白'
student.age = 16
@Configuration
@PropertySource(value="classpath:application.properties")
@ConfigurationProperties(prefix="student")
public class Student {
    public static String name;
    public static int age;
 
    public void setName(String name){
        Student.name = name;
    }
 
    public void setAge(int age){
        Student.age = age;
    }
}

4.还可以使用@Autowired注解对已经存在于IoC容器中的对象实现自动注入。

IoC的优缺点

优点:
可以灵活提供不同的子类实现(其实就是解耦),提高程序的灵活性、可扩展性和可维护性。由IOC容器通过配置文件来管理对象的生命周期、依赖关系等,这样就不用重新修改并编译具体的代码,从而实现组件之间的解耦。
缺点:
1、创建对象的步骤变复杂了,不直观,当然这是对不习惯这种方式的人来说的。
2、因为使用反射来创建对象,所以在效率上会有些损耗。但相对于程序的灵活性和可维护性来说,这点损耗是微不足道的。

本文参考:
http://jinnianshilongnian.iteye.com/blog/1413846
https://blog.csdn.net/tanglihai/article/details/81353411

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值