Sring核心特性之IOC(控制反转)和DI(依赖注入)
标签 :Spring
初学Spring框架一定最先接触IOC(控制反转)和DI(依赖注入)这两个概念,但是会对这两个概念混淆不清,今天我就Spring IOC分享一点自我的见解。
控制反转IoC(Inversion of Control-IoC)
控制反转不是什么技术,而是一种设计思想,ioc是将你自己设计好的对象交给Bean容器管理,而不是什么从对象的内部管理控制。设计好的对象是从类来的。控制反转的“控制”是IoC容器控制了对象,主要控制了外部资源的获取。“反转”的理解,因为IoC容器帮我们查找和注入依赖对象,对象都是被动的接受依赖对象。那些方面反转了?依赖对象的获取被反转了。
控制反转是通过依赖注入实现的。依赖注入是指容器负责创建对象和维护对象之间的依赖关系。依赖注入的主要目的是解耦,体现了一种“组合”的思想,大家可以这样想,当你想要你的类具备某些功能的时候,你是去继承一个具有此项功能的父类?还是组合另外一个具有这个功能的类呢?继承一个父类,子类和父类耦合增加,显然组合的方式是很好的解决。
SpringIoC容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到你需要的Bean中,Spring提供使用xml,注解,java配置,groovy配置实现Bean的创建和注入。
声明Bean的注解:
- @Component组件,没有明确的角色。
- @Service在业务逻辑层(service层)使用。
- @Repository在数据访问层(dao层)使用。
- @Controller在表现层(MVC–>Spring MVC)使用。
注入Bean的注解:
- @Autowired:Spring提供的注解。
- @Inject:JSR-330提供的注解。
- @Resource:JSR-250提供的注解。
上面三种注解都可以注在set方法上或者是属性上。但一般都习惯注在属性上,优点是代码更加少,层次更加清晰。
代码演示Bean的初始化和注入。
1、实现类的Bean:
package com.hellojava.springioctest;
import org.springframework.stereotype.Service;
/**
* @Author:yinjianping
* @Description:实现类的Bean
* @Date:Created in 23:28 2018/3/15
* @Modified By:
*/
//使用@Service注解声明当前类是Spring管理的一个Bean,使用@Component,
// @Repository,@Controller是等效的,根据需要选取
@Service
public class springIocTest {
public String sayHello(String word){
return "hello"+word+"!";
}
}
2、创建使用功能类的Bean:
package com.hellojava.springioctest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author:yinjianping
* @Description:使用功能类的bean
* @Date:Created in 23:52 2018/3/15
* @Modified By:
*/
@Service
public class doSpringIocTest {
/**
* 将springIocTest自动注入到当前类中,此处使用JSR-330的@Inject注解或是
* JSR-250的@Resource注解也是等效的
*/
@Autowired
springIocTest iocTest;
public String SayHello(String word){
return iocTest.sayHello(word);
}
}
3、配置类:
package com.hellojava.springioctest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @Author:yinjianping
* @Description:扫描包
* @Date:Created in 0:00 2018/3/16
* @Modified By:
*/
/**
* @Configuration注解是声明当前类是一个配置类
* @ComponentScan注解是自动扫描包中使用@Service等注解的类,并且注册为Bean
*/
@Configuration
@ComponentScan("com.hellojava.springioctest")
public class DiConfig {
}
4、创建Main类运行:
package com.hellojava.springioctest;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @Author:yinjianping
* @Description:
* @Date:Created in 0:06 2018/3/16
* @Modified By:
*/
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context=
new AnnotationConfigApplicationContext(DiConfig.class);
doSpringIocTest dospringIocTest=context.getBean(doSpringIocTest.class);
System.out.println(dospringIocTest.SayHello(" word"));
context.close();
}
}
5、运行结果:
DI(dependency injection-DI)
依赖注入:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
如何理解DI:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”?
- 谁依赖于谁:当然是应用程序依赖于IoC容器;
- 为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;
- 谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;
- 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
最后
如有理解不致的地方,请指证~!