1.Spring设计理念(最小侵入式,依赖注入,切面)
1.1 简化开发
Spring的目标是致力于全方位的简化Java程序的开发,那么Spring是如何做到这一点的呢?
Spring的设计理念总结为四点,如下:
- 基于POJO的轻量级和最小侵入式编程
- 通过依赖注入和面向接口实现类与类之间的松耦合
- 基于切面和惯例进行声明式编程实现一些通用功能
- 通过切面和模板减少样板式代码
Spring中所做的所有事的基础都可以追溯到上面的一条或多条!!
1.1.1 理解非侵入式概念
POJO就是简单的,不继承依赖外部类的独立的Java类,也就是说一个POJO可以独立的运行起来。(除了依赖jdk内部的一些类,它不依赖于任何的外部扩展类)
(1) 什么是侵入式编程
侵入式编程简单来说就是一种编程方式,它采用继承或依赖的的方式使类和类之间强耦合,从而导致灵活性下降,例如:
我们要实现一个DvdPlayer类和Video类,其中Video类继承了DvdPlayer类的播放方法使得Video具有播放功能,使用侵入式编程,我们可以这样写:
public class DvdPlayer{
public void play(String content){
System.out.println(content);
}
}
public class Video extends DvdPlayer{
private String content = "Hello is me";
public void playVideo(){
this.play(content);
}
public void setContent(String content){
this.content = content;
}
}
这样做了之后,Video就离不开DvdPlayer类了,没了DvdPlayer,Video就无法编译通过,如果DvdPlayer本身也继承了其他类,这就会引起连锁反应。侵入式编程会使整个项目向臃肿,复杂的方向上靠。
(2)非侵入式编程
了解了前面的侵入式编程,我们是否有一种其他的方式,既能实现上述功能,又能使其弱耦合呢?答案就是非侵入式编程,什么是非侵入式编程呢? 就是以组合接口的形式使类和类之间的关联依赖降低至类与接口的之间的关联,通过接口降低类与类之间的耦合性。
好,下面通过这种思想来解决上面的问题:
首先我们需要创建一个Dvd接口:
public interface Dvd{
public void play(String content);
}
然后Video类组合这个接口,并且提供注入实现Dvd接口的实体类的方式:
public class Video{
private Dvd dvdPlayer;
private String content = "Hello is me";
public void playVideo(){
dvdPlayer.paly(content);
}
public void setContent(String content){
this.content = content;
}
public void setDvd(Dvd dvdPlayer){
this.dvdPlayer = dvdPlayer;
}
}
这样做的好处是什么呢? 很明显,这样了之后,我们可以脱离DvePlayer进行独自编译,且可以提供play的多种实现方式并注入使用。但是这样做并不是完全的非侵入式编程,因为它确实还依赖了接口Dvd,所以称之为最小侵入式编程。
注意:上面提到的注入就是我们所说的依赖注入,也就是说类与类之间的依赖不通过硬编码的方式进行定义,而通过注入的方式进行定义,这样做灵活性更强。 关于依赖注入的详细内容将在下一节进行说明。
最后DvdPlayer实现Dvd接口即可
public class DvdPlayer implements Dvd{
public void play(String content){
System.out.println(content);
}
}
OK,了解了侵入式和非侵入式的含义,我们可以知道侵入式编程让类与类之间的耦合度很高,这样不利于系统的弹性变更,而非侵入式编程让类和类之间的耦合度很低,使系统更具弹性。
1.1.2 切面初了解
我们知道通过最小侵入式编程的依赖注入可以让类与类之间保持松耦合,那么如何实现代码的可重用性呢?
就是如何将那些重复的操作代码提取出来放在某一个地方,既能保持这个地方与他作用的类的松耦合,也能保持这个地方的代码发生作用?
举个例子,
我们现在有两个类,一个是学生实体类,另一个是教师实体类:
public class Student {
private String name;
private int age;
private String sex;
public Student(){}
public Student(String name,int age,String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public void disPlay() {
System.out.println("我的名字是:"+name);
}
public void speak(){
System.out.println("你好!!")
}
}
public class Teacher {
private String name;
private int age;
private String sex;
public Teacher(){}
public Teacher(String name,int age,String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public void disPlay() {
System.out.println("我的名字是:"+name);
}
public void speak(){
System.out.println("你好!!")
}
}
哎呀,这可是个糟糕的设计,很明显,教师类和学生类几乎一样,代码重复率高达90%,不行,我们得重新设计一下,于是,我先到了继承,通过继承来提高代码的重用性,这个方式怎么样呢? 我们先试试吧
首先,我们先建立一个Person类:
public class Person {
public String name;
public int age;
public String sex;
public Person(){}
public Person(String name,int age,String sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public void disPlay() {
System.out.println("我的名字是:"+name);
}
public void speak(){
System.out.println("你好!!")
}
}
然后,学生类是这样的:
public class Student extends Person{
public Student(){}
public Student(String name,int age,String sex){
super(name,age,sex);
}
}
老师类是这样的:
public class Teacher extends Person{
public Teacher(){}
public Teacher(String name,int age,String sex){
super(name,age,sex);
}
}
我们发现,这这样做确实能将重复的代码给抹掉,但是,这样一来,老师类和Person类的耦合度也上来了啊,我们又进入了侵入式编程噩梦。。。。
我们该如何摆脱现状呢? 这时,AOP出现了,面向切面编程,通过AOP理论,我们可以既能实现代码的复用,又能做到最小侵入式编程,AOP存在的意义大概就是如此吧。
1.2 了解Spring包含的各种组件
通过前面的了解,我们总结: Spring关注于通过依赖注入,面向切面编程等基础理论来简化企业级Java开发。
其实,Spring的功能不仅如此,在Spring框架范畴内,我们可以发现Spring简化Java开发的多种方式。除此之外,在Spring基础支持上,我们还可以构建庞大的生态圈:WEB服务,REST , 移动开发以及NoSQL。
下面让我们来了解下Spring框架的核心,来看看它究竟为我们带来了什么?
1.2.1 Spring模块
当我们去下载Spring发布版本时,我们会发现其lib依赖目录下有多个jar文件,其中大概有20多类的jar文件,每一类代表一个模块,我们可以选择其中某些模块进行使用,也可以都用,这看我们自己的选择。

其中,Core Container为我们提供了完整的依赖注入支持,这涉及到容器。 在这个基础上构建了AOP, Aspects,Messaging等模块。
好啦,现在去了解这些还为时尚早,就混个脸熟,等彻底理解的DI和AOP的精髓再去看这些也许就会变得简单。

浙公网安备 33010602011771号