Spring之旅
Spring为企业级开发提供丰富的功能,但是这些功能的底层都是依赖他的两个特性,也就是DI(依赖注入dependency injection)和AOP(面向切面编程aspect-oriented programming)
开始之前首先应该知道下面几个简称
POJO :Plain Old java Object 简单老式java对象
EJB:Enterprise javaBean 求二级javaBean
Spring的使命 简化java开发
为了降低java开发的复杂性,Spring采用了以下四种关键策略
-
基于POJO的轻量级和最小入侵性开发
-
通过依赖注入和面向接口实现送耦合
-
基于切面和惯例进行声明式编程
-
通过切面减少样式代码
依赖注入
依赖注入就是将锁以依赖的关系交给目标对象,而不是让目标对象自己去获取依赖
依赖注入为了解耦合
耦合具有两面性:
一方面:耦合禁魔的代码难以测试,难以复用,难以理解
另一方面,没有耦合的代码什么也做不了,所以要有一定程度的耦合
DamselRescuingKnight只能执行RescueDamselQuest探险任务
public class DamselRescuingKnight {
private RescueDamselQuest quest;
public DamselRescuingKnight(){
this.quest = new RescueDamselQuest();
}
public void embaekonQuest(){
quest.embaekon();
}
}
DamselRescuingKnight只能执行RescueDamselQuest探险任务
这个类中自己创建了RescueDamselQuest,使得DamselRescuingKnight和RescueDamselQuest紧密结合在一起
如果需要营救公主,他变召之即来,但是需要他消灭一条恶龙,他便爱莫能助.
而且更糟糕的是DamselRescuingKnight编写单元测试更加困难
/**
* BraveKnight足够灵活可以接受人格赋予他的探险任务
*/
public class BraveKnight implements Knight{
private Quest quest;
public BraveKnight(Quest quest) {
this.quest = quest;
}
public void embarkOnQuest(){
quest.embark();
}
}
BraveKnight没有自己创建探险任务,而是在构造的时候将探险作为构造参数传入,这是依赖注入的一种方式,构造注入
import org.junit.Test;
import static org.mockito.Mockito.*;
/**
* @auther zh
* @data 2018/12/3 15:28
*/
public class BraveKnightTest {
@Test
public void knightShouldEmbarkOnQuest(){
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest,times(1)).embark();
}
}
上面使用了mock框架的Mockito去创建一个Quest的接口mock实现,验证了Quest的mock实现的embark()只调用了一次