第二章-重新认识Spring IOC

本文详细介绍了Spring的IOC(控制反转)概念,包括IOC的发展历史、IoC容器的职责,特别是依赖注入的三种方式:构造函数注入、setter方法注入和接口注入,并对比了它们的优缺点。此外,还提到了依赖查找的概念及其两种类型:依赖拖拽和上下文依赖查找。
摘要由CSDN通过智能技术生成

第二章-重新认识Spring IOC

IOC的发展

  • 1983年,Richard E. Sweet 在《The Mesa Programming Environment》中提出“Hollywood
    Principle”(好莱坞原则)
  • 1988年,Ralph E. Johnson & Brian Foote 在《Designing Reusable Classes》中提出“Inversion
    of control”(控制反转)
  • 1996年,Michael Mattsson 在《Object-Oriented Frameworks, A survey of methodological
    issues》中将“Inversion of control”命名为 “Hollywood principle”
  • 2004年,Martin Fowler 在《Inversion of Control Containers and the Dependency Injection
    pattern》中提出了自己对 IoC 以及 DI 的理解
  • 2005年,Martin Fowler 在 《InversionOfControl》对 IoC 做出进一步的说明

IoC 容器的职责

依赖注入(Depedency Injection)

意思是自身对象中的内置对象是通过注入的方式进行创建。依赖注入有两种实现方式:Setter方式(传值方式)和构造器方式(引用方式)。

容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造子传递给需要的对象。

相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。

依赖注入三种方式
  • 构造函数注入
    IoC Service Provider会检查被注入对象的构造方法,取得它需要的依赖对象列表,进而为其注入响应的对象。同一个对象是不可能被构造两次的,因此,被注入对象的构造乃至整个生命周期,应该是由IoC Service Provider 来管理。
    构造方法注入方式比较直观,对象被构造完成后,即进入就绪状态,可以马上使用。这就好比你刚进酒吧的门,服务生已经将你喜欢的啤酒摆上了桌面一样。坐下来就可马上享受一份清凉与惬意。
  • Setter方法注入
    对于JavaBean对象来说,通常会通过setXXX()和getXXX()方法来访问对应属性。这些setXXX()方法统称为setter方法,getXXX()当然就统称为getter方法。通过setter方法,可以更改响应的对象属性,通过getter方法,可以获得响应属性的状态。所以,当前对象只要为其依赖对象所对应的属性添加setter方法,就可以通过setter方法将响应的依赖对象设置到被注入对象中。
    setter方法注入虽不像构造方法注入那样,让对象构造完成后即可使用,但相对来说更宽松一些,可以在对象构造完成后再注入。这就好比你可以去酒吧坐下后再决定要点什么啤酒,可以要百威,也可以要雪花,随意性比较强。如果你不急着喝,这种方法当然最适合你的。
  • 接口注入
    相对于前两种注入方式来说,接口注入没有那么简单明了。被注入对象如果想要IoC Service Provider 为其注入依赖对象,就必须实现某个接口。这个接口提供一个方法,用来为其注入依赖对象。IoC Service Provider 最终通过这些接口来了解应该为被注入对象注入什么依赖对象。
三种注入方式的比较
  • 接口注入:从注入方式的使用来说,接口注入是现在不甚提倡的一种方式,基本处于退役状态。因为它强制被注入对象实现不必要的接口,常有侵入性。而构造方法注入和setter方法注入则不需要如此。

  • 构造方法注入:这种注入方式的优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用。缺点就是,当依赖对象比较多的时候,构造方法的参数列表会比较长,而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。而且在Java中,构造方法无法被继承,无法设置默认值。对于非必须的依赖处理,可能需要引入多个构造方法,而参数数量的变动可能造成维护上的不便。

  • setter方法注入:因为方法可以命名,所以setter方法注入在描述性上要比构造方法注入好一些。另外,setter方法可以被继承,允许设置默认值,而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。

    综上所述,构造方法注入和setter方法注入因为其侵入性较弱,且易于理解和使用,所以是现在使用最多的注入方式,而接口注入因为侵入性较强,近年来已经不流行了。

依赖查找(Dependency Lookup)

谷歌中还有个资料表明:依赖查找也有两种类型:依赖拖拽(DP)和上下文化依赖查找(CDL)。

http://what-when-how.com/Tutorial/SpringFramework3/SpringFramework300052.html

依赖拖拽 (Dependency Pull)
依赖拖拽:注入的对象如何与组件发生联系,这个过程就是通过依赖拖拽实现 。(较少有使用)

依赖拖拽示例代码:

public class DependencyPullDemo {

public static void main(String[] args) {

    BeanFactory beanFactory = getBeanFactory();

    MessageService messageService = (MessageService) beanFactory.getBean("service");

    messageService.execute();

}

private static BeanFactory getBeanFactory() {

    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();

    BeanDefinitionReader reader = new PropertiesBeanDefinitionReader(beanFactory);

    reader.loadBeanDefinitions(new ClassPathResource("/META-INF/spring/ioc-pull-context.properties"));

    return beanFactory;

}

}

而通常对注入对象的配置可以通过一个 xml 文件完成。

依赖拖拽这种方式对对象进行集中管理。

上下文依赖查找(Contextualized Dependency Lookup)
在某些方面跟依赖拖拽类似,但是上下文依赖查找中,查找的过程是在容器管理的资源中进行的,而不是从集中注册表中,并且通常是作用在某些设置点上。

public class ContextualizedDependencyLookupDemo

{ 

    private static Set<ManagedComponent> components = new HashSet<ManagedComponent>();  

    private static class MessageServiceComponent implements ManagedComponent{ 

        private MessageService messageService;  

        public void lookup(BeanFactory beanFactory) { 

            this.messageService = (MessageService) beanFactory.getBean("service"); 

        } 

    }

}

使用依赖拖拽与上下文依赖查找本质的区别是:上下文依赖查找是在业务组件代码中进行的,而依赖拖拽是从一个集中的注册处,特定的地点执行。

Dependency Pull To a Java developer, Dependency Pull is the most familiar type of IoC. In Dependency Pull,dependencies are pulled from a registry as required.

对于Java开发人员来说,依赖拖拽是最常见的IoC类型。在依赖拖拽中,根据需要从注册表中提取依赖项。

Anyone who has ever written code to access an EJB(2.1 or prior versions) has used Dependency Pull (i.e., via the JNDI API to look up an EJB component).

任何编写过访问EJB(2.1或更早版本)的代码的人都使用过依赖拖拽(即,通过JNDI API查找EJB组件)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值