您的位置:首页 > 编程语言 > Java开发

(2) spring核心概念IOC/DI实例分析

2017-07-04 00:04 513 查看
一 IOC/DI的概念

IOC(Invesion of Control)控制反转,把传统意义上对象操纵权限交给容器处理,

由容器负责对象的初始化,配置和分配。引入IOC的目的,是为了解决松耦合性。

在IOC没有出现前,在面向对象编程中,要使用某个对象,总是通过new关键字来完成,

这样编程会导致程序中依赖于new对象。比如:

A a = new A();

B b = new B();

a.set(b);

本质上,直接实例化,直接获取依赖,直接装配。

缺点: 

一旦我们改变实现,需要重新编译;

生成者和消费者实例耦合;

而引入IOC后,通过配置文件,即可建立对象间依赖关系,从面向对象编程转变为

面向接口编程,大大提高代码的可重用性,可维护性,以及代码的性能。比如:

A a = BeanFactory.getBean("a");// 直接从容器中获取,返回已经装配好的a

IOC是一种设计模式,是工厂模式的升华,是一个大工厂,

把工厂方法中的对象抽象到配置文件来完成,然后再通过依赖注入

将容器实例注入到应用程序中去。IOC与DI不是一个东西,

可以理解为IOC为模式,DI为实现。

IoC是一个很大的概念,可以用不同的方式来实现。

其主要实现方式有两种:

(1)依赖查找(Dependency Lookup):容器提供回调接口和上下文环境给组件

(2)依赖注入(Dependency Injection):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

        后者是时下最流行的IoC类型,其又有接口注入(Interface Injection),设值注入(Setter Injection)

        和构造子注入(Constructor Injection)三种方式。

二 IOC容器

org.springframework.beans和org.springframework.context是spring实现IOC容器的两大核心包,

BeanFactory提供各种类型对象管理,被管理的对象,都统一称为bean ,

ApplicationContext作为BeanFactory的一个子接口,增强bean的管理功能。

ClassPathXmlApplicationContext和FileSystemXmlApplicationContext为

ApplicationContext两个典型实现,用于读取容器对象,资源等。

IOC容器负责读取元数据对这些bean实例化,配置,装配。

元数据配置有三种典型方式:XML配置,JAVA注解,JAVA code。

如何实例化容器?

比如:

ApplicationContext context =

new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});

我们一次可以读取多个spring配置文件,然后通过容器的getBean方法,获取实例化对象。

当让了,如果觉得初始化spring IOC容器时,觉得配置文件太多,我们可以通过拆分的方式

进行配置,xml按模块拆分成多个,通过import引入,初始化容器时读取主xml文件即可,

其余自然被引入。eg:

<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>


三 IOC实例

1. 新建一个接口(IHelloWordService.java)

package com.lanhuigu.spring.service;

public interface IHelloWordService {
String sayHello();
}


2. 接口实现(HelloWorldServiceImpl.java)

package com.lanhuigu.spring.service.impl;

import com.lanhuigu.spring.dao.HelloWorldDAO;
import com.lanhuigu.spring.service.IHelloWordService;

public class HelloWorldServiceImpl implements IHelloWordService{

private HelloWorldDAO helloWorldDAO;

/** 通过set方式注入bean */
//	public void setHelloWorldDAO(HelloWorldDAO helloWorldDAO) {
//		this.helloWorldDAO = helloWorldDAO;
//	}
/** 通过constructor方式注入bean*/
public HelloWorldServiceImpl(HelloWorldDAO helloWorldDAO) {
this.helloWorldDAO = helloWorldDAO;
}

@Override
public String sayHello() {
return helloWorldDAO.queryHelloWorld();
}

}


3. DAO模拟(HelloWorldDAO.java)
package com.lanhuigu.spring.dao;

public class HelloWorldDAO {

public String queryHelloWorld() {
return "Hello World!--DAO";
}

}
4. IOC容器通过XML形式配置元数据,将以上对象HelloWorldServiceImpl与HelloWorldDAO建立依赖关系
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 
<bean id="helloWorldService" class="com.lanhuigu.spring.service.impl.HelloWorldServiceImpl">
<!-- set方式注入 -->
<!-- <property name="helloWorldDAO" ref="helloWorldDAO"/> -->
<!-- constructor方式注入 -->
<constructor-arg ref="helloWorldDAO"/>
</bean>

</beans>
5. 测试代码
package com.lanhuigu.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lanhuigu.spring.service.IHelloWordService;

public class SpringHelloWorldTest {

public static void main(String[] args) {
// 读取spring配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取bean
IHelloWordService helloWorldService =
(IHelloWordService) context.getBean("helloWorldService");
// 调用接口方法
System.out.println(helloWorldService.sayHello());
}
}


代码分析:
在IOC没有使用前,如果想在HelloWorldServiceImpl中使用HelloWorldDAO,可以通过new的方式实现。
eg:
HelloWorldDAO helloWorldDAO = new HelloWorldDAO()
然后HelloWorldServiceImpl中直接使用装配的new对象,如果系统有上千个地方使用,
你需要new上千回,性能低,维护性也不好,代码耦合性极高,都依赖于new对象。
而现在使用IOC建立对象依赖关系,通过set注入或构造器注入(接口注入不建议使用,不常用),
HelloWorldServiceImpl方便快捷获取依赖对象HelloWorldDAO,这样就实现了IOC的宗旨,
把对象----》对象转化为对象---》容器----》对象管理,所有直接依赖对象均交由容器处理,
建立依赖,统一装配,松耦合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: