大话Spring(一) --- 初探IoC之控制反转

昨夜西风凋碧树,独上高楼,望尽天涯路

  在对Springboot以及SpringCloud有了一定初步的了解以及学习几个简单的前后端分离的demo之后,为了更加深入学习Spring家族这一轻量而又自动化的框架,在博客园连载记录学习Spring的点点滴滴                                

    ---cnblogs处女作

 

 


 

IoC浅谈

所谓IoC(Inversion of Control),也即控制反转,Spring两大核心之一。何为IoC呢?其并非是一种技术,而是一种设计思想。在OOP的指导思想下,若要创建对象,直接在内部通过new的语法即可完成,是为程序员手动创建

而对IoC而言,它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理,就是对组件对象控制权的转移,从程序代码本身转移到了外部容器,在Spring实现中,通过在配置文件中配置bean标签形式创建对象,交给Spring由Spring创建对象的过程,由Spring来负责控制对象的生命周期和对象间的关系

颇有一种交出先手,却收获满意的目数,也有一种反向代理的味道

IoC的作用很明显了,如:

  • 管理对象的创建和依赖关系的维护

  • 解耦,由容器去维护具体的对象

  • 托管了类的产生过程,比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的


 

实现

为了更加准确或者说使得IoC这一思想更加的与众不同,采用了DI(Dependency Injection由Martin Fowle在2004年初的一篇论文中首次提出的),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地(无时无刻不牵涉到反射这一Java重要的特征)将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系

Spring使用三种方式实现依赖注入,分别为接口注入(Interface Injection),Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象

接下来演示代码实现,并简述各种方式的优略

 1 //接口注入
 2 public interface UserMapper {
 3 
 4     void createUserMapper(UserMapper userMapper);
 5 
 6     void test();
 7 
 8 }
 9 
10 public interface UserService {
11 
12     void test();
13 
14 }
15 
16 //实现
17 public class UserServiceImpl implements UserService, UserMapper {
18 
19     private UserMapper userMapper;
20 
21     @Override
22     public void createUserMapper(UserMapper userMapper) {
23         this.userMapper = userMapper;
24     }
25 
26     @Override
27     public void test() {
28         userMapper.test();
29     }
30 
31 }

由于被强制被注入对象实现不必要的接口,带有侵入性

 

 1 //构造方法注入
 2 public class UserServiceImpl implements UserService {
 3 
 4     private UserMapper userMapper;
 5 
 6     /**
 7      * 构造方法注入
 8      * @param userMapper
 9      */
10     public UserServiceImpl(UserMapper userMapper) {
11         this.userMapper = userMapper;
12     }
13 
14     @Override
15     public void test() {
16         userMapper.test();
17     }
18 
19 }

该方法优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用,而缺点自然就是,当依赖对象比较多时,构造方法的参数列表会比较长,且构造方法无法被继承,无法设置默认值

 

 

 1 //setter方法注入
 2 public class UserServiceImpl implements UserService {
 3 
 4     private UserMapper userMapper;
 5 
 6     /**
 7      * setter方法注入
 8      * @param userMapper
 9      */
10     public void setUserMapper(UserMapper userMapper) {
11         this.userMapper = userMapper;
12     }
13 
14     @Override
15     public void test() {
16         userMapper.test();
17     }
18 
19 }

方法可以命名,描述性上要好很多,且也可以被继承,允许设置默认值,缺点是无法在构造完成后马上进入就绪状态

 


 

Spring 的 IoC 设计支持以下功能:

  • 依赖注入
  • 依赖检查
  • 自动装配
  • 支持集合
  • 指定初始化方法和销毁方法
  • 支持回调某些方法(但是需要实现 Spring 接口,略有侵入)

其中,最重要的就是依赖注入,从 XML 的配置上说,即 ref 标签。对应 Spring RuntimeBeanReference 对象

对于 IoC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入

 

 

 

 

 

posted @ 2020-08-07 23:27  CodePrince86  阅读(162)  评论(0)    收藏  举报