思维导图:
一.引言
新的一年,我要更加努力,所以我计划开始进行Spring的系统性总结,以前学习spring的知识都比较零散,所以这次买了一本<Spring实战>的第四版进行学习,所以,sping系列本质上都是我读这本书的读书总结吧.
Spring是相当庞大的生态圈,拥有许多的功能模块,但是,归根结底,Spirng的目的就四个字:简化开发.
二.简化Java开发
spring简化java开发的手段可以大致从4个方面来分析.
2.1 最小侵入性编程
什么事最小侵入性编程呢?按照我的理解来说,就是尽最大可能的不让spirng元素放入功能代码之中.比如:我需要一个类,他的功能就是大声的喊出"hello world",除此之外,要尽可能的不写入其他系统性的代码,比如日志,实例创建等.他只需要向下列代码一样就行了,至于其他的调用日志之类的东西,尽量不写入功能代码之中
public class HelloWorld{
public String say(){
return "hello world";
}
}
2.2 依赖注入DI
我所理解的依赖注入即是将bean实例的创建的控制权移交给Spirng而不是在代码中.而依赖注入的最大收益就是松耦合,通过和接口配合来达到此目的.
这篇文章不涉及到spring是如何实例化bean的.这将在下一篇中介绍.
先举一个反例,以下代码是传统的调用,其缺点是请求对象和交易耦合的太过紧密.
public class DamselRescuingKnight implements Knight {
private RescueDamselQuest quest;
public DamselRescuingKnight() {
this.quest = new RescueDamselQuest();//只能是这个请求实例,其他的都不行,耦合太紧
}
public void embarkOnQuest() {
quest.embark();
}
}
通过依赖注入,我们可以通过Spring控制对象的实例化,再配合接口,我们就可以做到请求对象和交易的松耦合,最后的效果就是互相协作的交易之间是松耦合的.而且会对不同类型的请求对象做不同的处理.为什么我们能这么做,因为bean的实例化控制权在Spirng手上
public class BraveKnight implements Knight {
private Quest quest;
public BraveKnight(Quest quest) {
this.quest = quest; //这个quest到底是什么实例对象可以通过依赖注入控制
}
public void embarkOnQuest() {
quest.embark();
}
}
以上就是我对依赖注入的理解
2.3 面向切向编程AOP
面向切向编程就是将遍布于系统各处的功能分离出来形成可重用的组件.一般来说,日志记录,事务管理,安全管理这些都是属于全系统中随时都要关注的要点,如果没有面向切向编程,这意味着我们必须随时在所有的交易中写入使用这些关注点的重复代码,而且会让功能代码变得不纯粹和混乱.比如在本文的一个例子中(hello world那个)难道,我在大声后出hello world 之前还有概述系统我要大喊大叫了,你记录一下,然后在喊完之后又告诉系统一声,我叫完了,你再记录一下?想想都头痛.
面向切向编程就是让代码的功能变得纯粹起来,其他的系统性的关注点会被模块化,然后通过声明的方式让他作用于我们希望作用的地方.如何声明我们将在下一篇文章中介绍.
2.4使用模板消除样板是代码
就我的感觉来说,我经常性的会写一些重复的代码,但是又不得不写,比如说自动化测试初始化数据.书上举例是JDBC,大致是一样的,我们要通过JDBC获取数据的话,就必然会写Connection,ResultSet什么的重复性的代码,Spring的解决办法是通过模块化的封装来消除样板式的代码,比如使用JdbcTemplate就可以达到不写上述重复代码而实现数据查询的功能.
三 bean容器
在基于Spring的应用中,应用对象生存与Spring容器(container)中,Spring容器负责创建对象,装配对象,配置对象,并管理bean的整个生命周期.Spirng自带有多个容器的实现,有一般来说,我们都使用上下文对象即什么什么Context那种,他可以管理到一个配置文件,这个配置文件就决定了bean是如何配置的,以及面向切向编程是如何申明的(不做具体描述).
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="knight" class="sia.knights.BraveKnight">
<constructor-arg ref="quest" />
</bean>
<bean id="quest" class="sia.knights.SlayDragonQuest">
<constructor-arg value="#{T(System).out}" />
</bean>
<bean id="minstrel" class="sia.knights.Minstrel">
<constructor-arg value="#{T(System).out}" />
</bean>
<aop:config>
<aop:aspect ref="minstrel">
<aop:pointcut id="embark"
expression="execution(* *.embarkOnQuest(..))"/>
<aop:before pointcut-ref="embark"
method="singBeforeQuest"/>
<aop:after pointcut-ref="embark"
method="singAfterQuest"/>
</aop:aspect>
</aop:config>
</beans>
然后Context对象就可以通过bean的id属性任意的加载bean对象了
下图是bean对象的生命周期,图中第三个至倒数第二个指的是实现了某一特殊接口以后,Spirng便可以在bean特定的生命时期做一些特定的处理
四.Spring的生态
Spring拥有一个为企业级开发所设计的巨大生态圈,几乎为企业级开发提供了一切,当然,我们可以选择使用其中的一些模块,也可以选择不使用.如下图:
当然,Spring又在以上模块之上构建了Spirng Portfolio,可以说Spirng Portfolio是构建与核心Spring框架之上的框架和类库,几乎为每一个领域的java开发都提供了Spring开发模型,比如Spirng boot,Spring Security等等
注:本篇文章由《Spring实战》第一章:Spring之旅 总结而来,由于本人非计算机专业出身,许多知识实在是理解不能,总结有相当多的遗漏,乃是我看不懂所致,更别说其中内容肯定有大量的理解错误,万望大家提出批评,我好改正。