本文基于《Spring实战(第4版)》所写。
Spring的最根本使命:简化Java开发。
为了降低Java开发的复杂性,Spring采取了以下4种关键策略:
- 基于POJO的轻量级和最小侵入性编程;
- 通过依赖注入和面向接口实现松耦合;
- 基于切面和惯例进行声明式编程;
- 通过切面和模版减少样板式代码;
先看一个简单的spring示例:勇敢的骑士完成杀恶龙的任务。
骑士接口
package com.springinaction;
public interface Knight {
void embarkOnQuest();
}
任务接口
package com.springinaction;
public interface Quest {
void embark();
}
勇敢的骑士类,没有任何spring额外的代码,保证了最小的侵入性
package com.springinaction;
public class BraveKnight implements Knight {
private Quest quest;
public BraveKnight(Quest quest){
this.quest = quest;
}
@Override
public void embarkOnQuest() {
quest.embark();
}
}
杀恶龙的任务类,没有任何spring额外的代码,保证了最小的侵入性
package com.springinaction;
import java.io.PrintStream;
public class SlayDragonQuest implements Quest {
private PrintStream stream;
public SlayDragonQuest(PrintStream stream){
this.stream = stream;
}
@Override
public void embark() {
stream.println("Embarking on quest to slay the dragon!");
}
}
吟唱诗人类,用于实现AOP的代码
package com.springinaction;
import java.io.PrintStream;
public class Minstrel {
private PrintStream stream;
public Minstrel(PrintStream stream){
this.stream = stream;
}
public void singBeforeQuest(){
stream.println("Fa la la, the knight is so brave!");
}
public void singAfterQuest(){
stream.println("Tee hee hee,the brave knight " +
"did embark on a quest");
}
}
spring的配置文件:knights.xml
<?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-3.2.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--勇敢骑士类的bean,其中构造器依赖注入了"quest"的bean-->
<bean id="knight" class="com.springinaction.BraveKnight">
<constructor-arg ref="quest"></constructor-arg>
</bean>
<!--杀恶龙类的bean,其中构造器的参数指定的是System.out-->
<bean id="quest" class="com.springinaction.SlayDragonQuest">
<constructor-arg value="#{T(System).out}"/>
</bean>
<!--吟唱诗人的bean,其中构造器的参数指定的是System.out-->
<bean id="minstrel" class="com.springinaction.Minstrel">
<constructor-arg value="#{T(System).out}"/>
</bean>
<aop:config>
<!--aop引用指向吟唱诗人的bean-->
<aop:aspect ref="minstrel">
<!--aop切入点定义以及规则表达式-->
<aop:pointcut id="embark" expression="execution(* *.embarkOnQuest(..))"/>
<!--aop的前置通知-->
<aop:before pointcut-ref="embark" method="singBeforeQuest"/>
<!--aop的后置通知-->
<aop:after pointcut-ref="embark" method="singAfterQuest"/>
</aop:aspect>
</aop:config>
</beans>
启动spring
package com.springinaction;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App
{
public static void main( String[] args ) throws Exception
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("knights.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close();
}
}
测试结果
Fa la la, the knight is so brave!
Embarking on quest to slay the dragon!
Tee hee hee,the brave knight did embark on a quest
以上示例印证了关键策略的前3个,最后的“通过切面和模版减少样板式代码”可以通过简化JDBC的spring的jdbcTemlate来体现,以下代码简化了JDBC的样板代码:
Spring-JdbcTemplateSpring容器
Spring的容器实现可以归为2种:bean工厂和应用上下文。
因为bean工厂比较低级,我们在这只讨论应用上下文。下面罗列的几个是最有可能遇到的。
- AnnotationConfigApplicationContext:从一个或多个基于Java的配置类中加载Spring应用上下文。
- AnnotationConfigWebApplicationContext:从一个或多个基于Java的配置类中加载Spring Web应用上下文。
- ClassPathXmlApplicationContext:从类路径下的一个或多个XML配置文件中加载上下文定义,把应用上下文的定义文件作为类资源。
- FileSystemXmlapplicationcontext:从文件系统下的一个或多个XML配置文件中加载上下文定义。
- XmlWebApplicationContext:从Web应用下的一个或多个XML配置文件中加载上下文定义。
Bean的生命周期
下图展示了Bean整个生命周期的过程:
Bean的生命周期俯瞰Spring风景线
Spring的框架划分为6类不同的功能,如下图所示:
Spring框架Spring Portfolio提供了一些核心框架之外的模块,包括:Spring Web Flow、Spring Web Service、Spring Security、Spring Integration、Spring Batch、Spring Data、Spring Social、Spring Mobile、Spring for Android、
Spring Boot
网友评论