重点-spring核心之一
IoC:Inverse of Control(控制反转):
读作“反转控制”,更好理解,不是什么技术,而是一种设计思想,好比于MVC。就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。
正控:若调用者需要使用某个对象,其自身就得负责该对象的创建。
反控:调用者只管负责从Spring容器中获取需要使用的对象,不关心对象的创建过程,也就是把创建对象的控制权反转给了Spring框架。
(Don’t call me ,I’ll call you)
DI:Dependency Injection(依赖注入)
从字面上分析:
IoC:指将对象的创建权,反转给了Spring容器;
DI :指Spring创建对象的过程中,将对象依赖属性(简单值,集合,对象)通过配置设值给该对象。
IoC和DI其实是同一个概念的不同角度描述,DI相对IoC而言,明确描述了“被注入对象依赖IoC容器配置依赖对象”。
Container:容器,在生活中容器就是一种盛放东西的器皿,从程序设计角度看作是装对象的对象,因为存在对对象的存入、取出等操作,所以容器还要管理对象的生命周期。
Spring号称是一个可以实现模块可插拔的JavaEE开发框架。那么它是如何实现程序的可插拔的呢?
实现程序可以插拔的核心理念就是,控制反转(Inversion of Control,英文缩写为IoC)
所谓的控制反转,就是将代码的调用权从调用方转移给被调用方(服务提供方)。
如图所示:
如下图:将A类调用B类的对象修改为C类的对象,修改的是被调用方的配置文件的代码,所以代码的调用权转移到了被调用方。通过控制反转,我们可以实现增加模块或者移除模块统一由配置文件关联,增加或者移除模块,配置XML配置文件即可。
我们将代码的调用权(控制权)从调用方转移给被调用方(服务提供方)的设计模式称为控制反转(IoC)
根据上图可以的得出,实现一个IoC的框架,必须要解决两个问题:
1.被调用方(服务方),在程序启动时就要创建好对象,放在一个容器里面。
2.调用方使用一个接口或类的引用(不用使用new),就可以创建获得对象。
我们将这种不用new,而是根据接口或者类的引用就可以从被调用的容器里获得创建的对象的方式称为依赖注入。
所以,控制反转(Ioc),就是依赖注入加上面向接口的编程思想的实现。
在这里,我们首先抓住一个重点:Spring之所以可以实现可插拔程序,是实现了不用new,使用类或接口就可以获得获得对象!
package cn.xc.spring.service;
public interface CustomService {
/**
* 保存方法
*/
public void save();
}
package cn.xc.spring.service.impl;
import cn.xc.spring.service.CustomService;
public class CustomServiceImpl1 implements CustomService {
@Override
public void save() {
System.out.println("CustomServiceImpl1.save()");
}
}
package cn.xc.spring.service.impl;
public class CustomServiceImpl2 implements cn.xc.spring.service.CustomService {
@Override
public void save() {
System.out.println("CustomServiceImpl2.save()");
}
}
package cn.xc.spring.client;
import cn.xc.spring.service.CustomService;
public class CustomClient {
private CustomService service;
public void save() {
service.save();
}
//此set方法是给Spring 依赖注入使用的方法(set方法注入,属性注入
public void setCustomService(CustomService service) {
this.service = service;
}
}
<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="client" class="cn.xc.spring.client.CustomClient">
<property name="customService" ref="service1">property>
bean>
<bean id="service1" class="cn.xc.spring.service.impl.CustomServiceImpl1">bean>
<bean id="service2" class="cn.xc.spring.service.impl.CustomServiceImpl2">bean>
beans>
package cn.xc.spring.test;
import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.xc.spring.client.CustomClient;
public class SpringTest {
@Test
public void testName() throws Exception {
// 1.读取Spring配置文件,启动Spring框架,创建Spring容器对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
// 2.从容器获取 CustomClient
CustomClient customClient = context.getBean("client", CustomClient.class);
customClient.save();
}
}