构造器注入
package sia.knights;
public class BraveKnight implements Knight {
private Quest quest;
//注入进来,构造器注入
public BraveKnight(Quest quest) {
this.quest = quest;
}
public void embarkOnQuest() {
quest.embark();
}
}
public interface Quest {
void embark();
}
public class BraveKnightTest {
@Test
public void knightShouldEmbarkOnQuest() {
Quest mockQuest = mock(Quest.class);//创建mock Quest
BraveKnight knight = new BraveKnight(mockQuest);//创建一个新的BraveKnight实例,构造器注入mock Quest
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();//验证embark()方法仅仅被调用了一次
}
}
java配置
@Configuration
public class KnightConfig {
@Bean
public Knight knight() {
return new BraveKnight(quest());
}
@Bean
public Quest quest() {
return new SlayDragonQuest(System.out);
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--注入quest bean -->
<bean id="knight" class="sia.knights.BraveKnight">
<constructor-arg ref="quest" />
</bean>
<!--创建SlayDragonQuest对象,作为BraveKnight的构造参数,把system.out作为参数传入SlayDragonQuest中-->
<bean id="quest" class="sia.knights.SlayDragonQuest">
<constructor-arg value="#{T(System).out}" />
</bean>
</beans>
public class KnightMain {
public static void main(String[] args) throws Exception {
//加载spring上下文
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext(
"META-INF/spring/knight.xml");
//获取Knightbean
Knight knight = context.getBean(Knight.class);
//使用knight
knight.embarkOnQuest();
context.close();
}
}
public class SlayDragonQuest implements Quest {
private PrintStream stream;
public SlayDragonQuest(PrintStream stream) {
this.stream = stream;
}
public void embark() {
stream.println("Embarking on quest to slay the dragon!");
}
}
应用切面Aop能够使服务模块化,以声明的方式将它们应用到它们需要影响的组件中去,使组件具有更高的内聚性并且更加关注自身的业务,不需要了解涉及系统服务所带来的复杂性
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!");
}
}
<?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>
<!--声明Minstrel 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>
bean应用对象生存于Spring容器中,Spring负责创建对象,装配对象,配置并管理整个生命周期。Spring容器使用DI管理构成应用的组件,会创建相互协作的组件之间的关联,spring容器分为俩种类型,bean工厂和应用上下文,bean工厂提供基本的DI支持,应用上下文基于BeanFactory构建,并提供应用框架级别的服务,例如从属性文件解析文本信息以及发布应用事件给事件监听者
应用上下文
AnnotationConfigApplicationContext : 从一个或多个基于 Java 的配置类中加载 Spring 应用上下文。
AnnotationConfigWebApplicationContext : 从一个或多个基于 Java 的配置类中加载 Spring Web 应用上下文
ClassPathXmlApplicationContext : 从类路径下的一个或多个 XML 配置文件中加载上下文定义, 把应用上下文的定义文件作为类资源
FileSystemXmlapplicationcontext : 从文件系统下的一个或多个 XML 配置文件中加载上下文定义
XmlWebApplicationContext : 从 Web 应用下的一个或多个 XML 配置文件中加载上下文定义。
加载
一个是从文件系统路径下找,一个是在类路径下找
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/knight.xml");
ApplicationContext context2 = new FileSystemXmlApplicationContext("c:/knight.xml");
从java配置中加载上下文
AnnotationConfigApplicationContext context3 = new AnnotationConfigApplicationContext(com.springination.knights.config.KnightConfig.class);
调用上下文的getBean()方法从Spring容器中获取bean
bean的生命周期
1 . Spring 对 bean 进行实例化;
2 . Spring 将值和 bean 的引用注入到 bean 对应的属性中;
3 . 如果 bean 实现了 BeanNameAware 接口, Spring 将 bean 的 ID 传递给 setBean-Name() 方法;
4 . 如果 bean 实现了 BeanFactoryAware 接口, Spring 将调用 setBeanFactory() 方法, 将 BeanFactory 容器实例传入;
5 . 如果 bean 实现了 ApplicationContextAware 接口, Spring 将调用 setApplicationContext() 方法, 将 bean 所在的应用上下文的引用传入进来;
6 . 如果 bean 实现了 BeanPostProcessor 接口, Spring 将调用它们的 post-ProcessBeforeInitialization() 方法;
7 . 如果 bean 实现了 InitializingBean 接口, Spring 将调用它们的 after-PropertiesSet() 方法。 类似地, 如果 bean 使用 initmethod 声明了初始化方法, 该方法也会被调用;
8 . 如果 bean 实现了 BeanPostProcessor 接口, Spring 将调用它们的 post-ProcessAfterInitialization() 方法;
9 . 此时, bean 已经准备就绪, 可以被应用程序使用了, 它们将一直驻留在应用上下文中, 直到该应用上下文被销毁;
10 . 如果 bean 实现了 DisposableBean 接口, Spring 将调用它的 destroy() 接口方法。 同样, 如果 bean 使用 destroy-method 声明了销毁方法, 该方法也会被调用。
spring模块
Spring 核心容器
容器是Spring框架最核心的部分, 它管理着Spring应用中bean的创建、配置和管理。 在该模块中, 包括了Spring bean工厂, 它为Spring提供了DI的功能。 基于bean工厂, 我们还会发现有多种Spring应用上下文的实现, 每一种都提供了配置Spring的不同方式。除了bean工厂和应用上下文, 该模块也提供了许多企业服务, 例如Email、 JNDI访问EJB集成和调度。所有的Spring模块都构建于核心容器之上。 当配置应用时, 其实隐式地使用了这些类。
在AOP模块中,Spring对面向切面编程提供了丰富的支持。 这个模块是Spring应用系统中开发切面的基础。 与DI一样,AOP可以帮助应用对象解耦。 借助于AOP, 可以将遍布系统的关注点(例如事务和安全) 从它们所应用的对象中解耦出来
使用 JDBC 编写代码通常会导致大量的样板式代码, 例如获得数据库连接、 创建语句、 处理结果集到最后关闭数据库连接。 Spring 的 JDBC 和 DAO ( Data Access Object ) 模块抽象了这些样板式代码, 使我们的数据库代码变得简单明了, 还可以避免因为关闭数据库资源失败而引发的问题。 该模块在多种数据库服务的错误信息之上构建了一个语义
丰富的异常层, 以后我们再也不需要解释那些隐晦专有的 SQL 错误信息了!对于那些更喜欢 ORM ( Object-Relational Mapping ) 工具而不愿意直接使用 JDBC 的开发者, Spring 提供了 ORM 模块。 Spring 的 ORM 模块建立在对 DAO 的支持之上, 并为多个 ORM 框架提供了一种构建 DAO 的简便方式。 Spring 没有尝试去创建自己的 ORM 解决方案, 而是对许多流行的 ORM 框架进行了集成, 包括 Hibernate 、 Java Persisternce API 、 Java Data Object 和 iBATIS SQL Maps 。 Spring 的事务管理支持所有的 ORM 框架以及 JDBC 。 本模块同样包含了在 JMS ( Java Message Service ) 之上构建的 Spring 抽象层, 它会使用消息以异步的方式与其他应用集成。 从 Spring 3.0 开始, 本模块还包含对象到 XML 映射的特性, 它最初是 Spring WebService 项目的一部分。除此之外, 本模块会使用 Spring AOP 模块为 Spring 应用中的对象提供事务管理服务。
Web 与远程调用
MVC ( Model-View-Controller ) 模式是一种普遍被接受的构建 Web 应用的方法, 它可以帮助用户将界面逻辑与应用逻辑分离。 Java 从来不缺少 MVC 框架, Apache 的 Struts 、 JSF 、 WebWork 和 Tapestry 都是可选的最流行的 MVC 框架。 虽然 Spring 能够与多种流行的 MVC 框架进行集成, 但它的 Web 和远程调用模块自带了一个强大的 MVC 框架, 有助于在 Web 层提升应用的松耦合水平。 除了面向用户的 Web 应用, 该模块还提供了多种构建与其他应用交互的远程调用方案。 Spring 远程调用功能集成了 RMI ( Remote Method Invocation ) 、 Hessian 、 Burlap 、 JAX-WS , 同时 Spring 还自带了一个远程调用框架: HTTP invoker 。 Spring 还提供了暴露和使用 REST API 的良好支持。
Instrumentation
Spring 的 Instrumentation 模块提供了为 JVM 添加代理( agent ) 的功能。具体来讲, 它为 Tomcat 提供了一个织入代理, 能够为 Tomcat 传递类文件, 就像这些文件是被类加载器加载的一样。 这个模块所提供的 Instrumentation 使用场景非常有限
测试
鉴于开发者自测的重要性, Spring提供了测试模块以致力于Spring应用的测试。通过该模块, 你会发现Spring为使用JNDI、 Servlet和Portlet编写单元测试提供了一系列的mock对象实现。 对于集成测试, 该模块为加载Spring应用上下文中的bean集合以及与Spring上下文中的bean进行交互提供了支持
Spring Portfolio
Spring Web Flow
Spring Web Flow建立于Spring MVC框架之上, 它为基于流程的会话式Web应用(可以想一下购物车或者向导功能) 提供了支持。
Spring Web Service
虽然核心的Spring框架提供了将Spring bean以声明的方式发布为WebService的功能, 但是这些服务是基于一个具有争议性的架构(拙劣的契约后置模型) 之上而构建的。 这些服务的契约由bean的接口来决定。 Spring Web Service提供了契约优先的Web Service模型, 服务的实现都是为了满足服务的契约而编写的。
Spring Security
安全对于许多应用都是一个非常关键的切面。 利用Spring AOP,Spring Security为Spring应用提供了声明式的安全机制。
Spring Integration
许多企业级应用都需要与其他应用进行交互。 Spring Integration提供了多种通用应用集成模式的Spring声明式风格实现。
Spring Batch
当我们需要对数据进行大量操作时, 没有任何技术可以比批处理更胜任这种场景。 如果需要开发一个批处理应用, 你可以通过SpringBatch, 使用Spring强大的面向POJO的编程模型
Spring Data
Spring Data使得在Spring中使用任何数据库都变得非常容易。 尽管关系型数据库统治企业级应用多年, 但是现代化的应用正在认识到并不是所有的数据都适合放在一张表中的行和列中。 一种新的数据库种类, 通常被称之为NoSQL数据库, 提供了使用数据的新方法, 这些方法会比传统的关系型数据库更为合适。不管你使用文档数据库, 如MongoDB, 图数据库, 如Neo4j, 还是传统的关系型数据库, Spring Data都为持久化提供了一种简单的编程模型。 这包括为多种数据库类型提供了一种自动化的Repository机制,它负责为你创建Repository的实现。
Spring Social
社交网络是互联网领域中新兴的一种潮流, 越来越多的应用正在融入社交网络网站, 例如Facebook或者Twitter。 如果对此感兴趣, 你可以了解一下Spring Social, 这是Spring的一个社交网络扩展模块。不过, Spring Social并不仅仅是tweet和好友。 尽管名字是这样, 但Spring Social更多的是关注连接(connect) , 而不是社交(social) 。它能够帮助你通过REST API连接Spring应用, 其中有些Spring应用可能原本并没有任何社交方面的功能目标。
Spring Mobile
移动应用是另一个引人瞩目的软件开发领域。 智能手机和平板设备已成为许多用户首选的客户端。 Spring Mobile是Spring MVC新的扩展模块, 用于支持移动Web应用开发
Spring for Android
与Spring Mobile相关的是Spring Android项目。 这个新项目, 旨在通过Spring框架为开发基于Android设备的本地应用提供某些简单的支持。最初, 这个项目提供了Spring RestTemplate的一个可以用于Android应用之中的版本。 它还能与Spring Social协作, 使得原生应用可以通过REST API进行社交网络的连接。
Spring Boot
Spring极大地简化了众多的编程任务, 减少甚至消除了很多样板式代码, 如果没有Spring的话, 在日常工作中你不得不编写这样的样板代码。 Spring Boot是一个崭新的令人兴奋的项目, 它以Spring的视角,致力于简化Spring本身。Spring Boot大量依赖于自动配置技术, 它能够消除大部分(在很多场景中, 甚至是全部) Spring配置。 它还提供了多个Starter项目, 不管你使用Maven还是Gradle, 这都能减少Spring工程构建文件的大小