# 开始spring之旅
## 历史
javabean -> EJB -> spring
## why
spring 简化了企业级系统开发. 原因是EJB太复杂了
1.好的设计比实现技术更重要
2.通过接口耦合的javabean是一个很好的模型
3.代码应该容易被测试
spring是一个轻量级的IOC和AOP框架。
## spring模块
1.core
2.AOP
3.O/R 映射
4.web context
5.applicaiton context
6.jdbc & dao
7.mvc
## spring hello world
首选写接口类
public interface GreetingService {
public void sayHello();
}
第二步实现类
public class GreetingServiceImpl implements GreetingService {
private String greeting;
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
public void sayHello() {
System.out.println(this.greeting);
}
}
第三步 配置bean.xml
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-3.0.xsd">
hello world
第四步 使用
public class main {
public static void main(String [] args) {
ClassPathResource resource = new ClassPathResource("beans/beans.xml");
System.out.println(resource.getPath());
BeanFactory factory = new GenericXmlApplicationContext(resource);
GreetingService greeting = (GreetingService) factory.getBean("greetService");
greeting.sayHello();
}
}
但是这样使用和
GreetingService greeting = new GreetingServiceImpl()
相比为一个的区别就是把GreetingService的实例化用配置来代替了. 这就是传说中的IOC
##理解IOC
IOC ,即反转控制。 是spring的核心。
当然用 依赖注入来解释会更容易理解。 当A使用了B, 在A实例化的时候,也必须实例化B,表明类A对B有了依赖。 我们把B的实例化抽取出来,而是采用在外部系统控制B的实例化并负责注入到A中,这样就实现了A和B的耦合。这就是所谓的依赖注入。
## IOC例子
骑士找圣杯
public class KnightOfRoundTable {
private String name;
private HolyGrailQuest quest;
public KnightOfRoundTable(String name) {
this.name = name;
this.quest = new HolyGrailQuest();
}
public HolyGrail embarkOnQuest(){
return quest.embark();
}
}
当我们写单元测试的时候会发现当写了KnightOfRoundTable的时候顺带把HolyGrailQuest 也写进去了。 因为KnightOfRoundTable 和 HolyGrailQuest 耦合在一起了。
耦合的代码
-难以测试, 难以使用,带来典型的"摧毁大堤"的bug
-但是没有耦合的代码什么也做不了
所以我们要管理耦合
其最常见的一个方法就是面向接口编程
public interface IQuest {
public HolyGrail embark();
}
同样:
public interface IKnight {
HolyGrail embarkOnQuest();
}
在 KnightOfRoundTable 中,就需要把任务装配进去
public void setQuest(IQuest quest) {
this.quest = quest;
}
然后配置bean:
undefinedundefined
John
创建系统组件之间关联的动作叫做装配。spring中有很多装配的方式,其中XML是最常见的一种。
以上是以来控制的全部: 协调依赖对象之间合作的责任,从对象之间释放出来。
## 应用AOP
理想的系统是有很多组件组成,每一个组件负责其中一部分的功能。但是实际情况是像日志管理这样的组件,进程侵入到其他系统中。
回答上面的例子, 我们假设需求变更了, 每一次骑士做任务之前,都需要配置一个吟游诗人来歌颂他的事迹
public HolyGrail embarkOnQuest(){
this.mistrel.compose(this.name, "embark");
return quest.embark();
}
那么问题来了, 其实必须每一次都主动触发 mistrel 去干什么。但是骑士骑士不用关心 mistrel 干了什么事情的。简单的说 mistrel 提供的服务超出了骑士本来的责任,也就是说mistrel和骑士的服务交叉在一起了。所以把mistrel实现成切面,并把他的服务提供给骑士是合理的。
public class Minstrel implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable {
IKnight knight = (IKnight)target;
String name = knight.getName();
System.out.println(name + ":" + knight.embarkOnQuest().toString());
}
}
配置bean
chaper01.knight.IKnight
minstrel
最典型的应用就是数据库的事物。