spring框架
一个开源框架
依赖注入(DI)
Spring 最认同的技术是控制反转的依赖注入(DI)模式。控制反转(IoC)是一个通用的概念,它可以用许多不同的方式去表达,依赖注入仅仅是控制反转的一个具体的例子。
当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入(或者有时被称为配线)有助于将这些类粘合在一起,并且在同一时间让它们保持独立。
到底什么是依赖注入?让我们将这两个词分开来看一看。这里将依赖关系部分转化为两个类之间的关联。例如,类 A 依赖于类 B。现在,让我们看一看第二部分,注入。所有这一切都意味着类 B 将通过 IoC 被注入到类 A 中。
依赖注入可以以向构造函数传递参数的方式发生,或者通过使用 setter 方法 post-construction。由于依赖注入是 Spring 框架的核心部分,所以我将在一个单独的章节中利用很好的例子去解释这一概念。
面向方面的程序设计(AOP):
Spring 框架的一个关键组件是面向方面的程序设计(AOP)框架。一个程序中跨越多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。有各种各样常见的很好的关于方面的例子,比如日志记录、声明性事务、安全性,和缓存等等。
在 OOP 中模块化的关键单元是类,而在 AOP 中模块化的关键单元是方面。AOP 帮助你将横切关注点从它们所影响的对象中分离出来,然而依赖注入帮助你将你的应用程序对象从彼此中分离出来。
Spring 框架的 AOP 模块提供了面向方面的程序设计实现,可以定义诸如方法拦截器和切入点等,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于.Net属性的方式合并行为信息到代码中。
spring的体系结构,它为开源人员提供了20个模块,可以根据实际用途使用他们。
核心容器由spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring表达式语言,Spring Expression Language)等模块组成,它们的细节如下:
spring-core模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。
context模块建立在由core和 beans 模块的基础上建立起来的,它以一种类似于JNDI注册的方式访问对象。Context模块继承自Bean模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过Servelet容器)等功能。Context模块也支持Java EE的功能,比如EJB、JMX和远程调用等。ApplicationContext接口是Context模块的焦点。spring-context-support提供了对第三方库集成到Spring上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。
spring-expression模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是JSP2.1规范中定义的统一表达式语言的扩展,支持set和get属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从Spring IoC容器检索对象,还支持列表的投影、选择以及聚合等。
数据访问/集成
数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:
(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)
JDBC 模块提供了JDBC抽象层,它消除了冗长的JDBC编码和对数据库供应商特定错误代码的解析。
ORM 模块提供了对流行的对象关系映射API的集成,包括JPA、JDO和Hibernate等。通过此模块可以让这些ORM框架和spring的其它功能整合,比如前面提及的事务管理。
OXM 模块提供了对OXM实现的支持,比如JAXB、Castor、XML Beans、JiBX、XStream等。
JMS 模块包含生产(produce)和消费(consume)消息的功能。从Spring 4.1开始,集成了spring-messaging模块。。
事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。(注:编程式事务需要自己写beginTransaction()、commit()、rollback()等事务管理方法,声明式事务是通过注解或配置由spring自动处理,编程式事务粒度更细)
Web
Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:
Web 模块提供面向web的基本功能和面向web的应用上下文,比如多部分(multipart)文件上传功能、使用Servlet监听器初始化IoC容器等。它还包括HTTP客户端以及Spring远程调用中与web相关的部分。。
Web-MVC 模块为web应用提供了模型视图控制(MVC)和REST Web服务的实现。Spring的MVC框架可以使领域模型代码和web表单完全地分离,且可以与Spring框架的其它所有功能进行集成。
Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。
Web-Portlet 模块提供了用于Portlet环境的MVC实现,并反映了spring-webmvc模块的功能。
其他
还有其他一些重要的模块,像 AOP,Aspects,Instrumentation,Web 和测试模块,它们的细节如下:
AOP 模块提供了面向方面的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于.Net属性的方式合并行为信息到代码中。
Aspects 模块提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。
Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。
Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。
测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试。
想要在Java项目内使用spring,必须引入四个基础包。
commons-logging-1.1.1
spring-beans-4.1.6.RELEASE
spring-context-4.1.6.RELEASE
spring-core-4.1.6.RELEASE
spring-expression-4.1.6.RELEASE
创建bean配置文件,这个文件可以简单地理解是一个类的容器,它可以在文件内部配置许多的类。
而想要使用配置文件,还需要实例化接口ApplicationContext, 而实例化的接口最常用的有三个类。
FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径。
ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
BeanFactory是一个容器,它主要的功能是为依赖注入提供支持,在spring中有很多对该接口的实现XmlBeanFactory 类。
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
spring Bean的定义。
被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建。
bean定义包含称为配置元数据,配置元数据有 创建一个bean bean的生命周期 bean的依赖关系。
bean可以为类设置以下属性
id class name scope constructor-arg properties autowiring mode
lazy-initiallization mode initialization destruction
class是为bean的类型,必须拥有,指定类的完整路径。
id是指向bean类的唯一标识,内部bean可以不含有。
name是类的属性,运用这个属性,必须在类定义时设计匹配的setter方法。
constructor-arg是类的构造器实现。
properties是类的属性实现总标签容器。
Spring IoC 容器完全由实际编写的配置元数据的格式解耦。有下面三个重要的方法把配置元数据提供给 Spring 容器:
基于 XML 的配置文件
基于注解的配置
基于 Java 的配置
bean的一些实现例子
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
bean的作用域
singleton在spring IoC容器仅存在一个Bean实例,Bean以单例方式存在,默认值。用==方式判断引用同一个bean单例,返回true。
prototype
每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行newXxxBean(),用==判断引用同一个bean单例,返回false。
request
每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境。
session
同一个HTTP Session共享一个Bean,不同Session使用不同的Bean,仅适用于WebApplicationContext环境。
global-session 使用的很少。
Bean 定义继承
bean 定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息例如初始化方法,静态工厂方法名,等等。
子 bean 的定义继承父定义的配置数据。子定义可以根据需要重写一些值,或者添加其他值。
使用parent属性可以指定父类,用ID设置。
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>
<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>
bean定义模板
实现是创建一个bean作为基础的父类,把它设置成抽象bean,除了不能实例化外,它拥有其他bean的属性。
abstract=”true”
bean依赖注入
依赖注入可以通俗地理解为类设置属性值,可以直接用属性的setter方法设置,也可以通过构造器方法设置属性值。
bean的依赖注入,depend-on属性,绑定与另一个存在依赖关系,依赖关系的类并不一定需要实现。
使用构造器函数注入配置。
要用constructor-arg标签设置,区分构造函数的参数,可以用index属性,或者type属性识别参数,或者按照默认顺序写标签。
<constructor-arg ref="spellChecker"/> ref引用。
<constructor-arg type="int" value="2001"/>
<constructor-arg index="0" value="2001"/>
使用命名空间为属性设置值是非常方便的,但需要引入特定的包依赖。
<bean id="john-classic" class="com.example.Person">
<property name="name" value="John Doe"/>
<property name="spouse" ref="jane"/>
</bean>
<bean id="john-classic" class="com.example.Person"
p:name="John Doe"
p:spouse-ref="jane"/>
</bean>
注入内部bean,内部bean不能被外部的bean用ref引用,如果引用了会报错。
spring注入集合
list set map props
后面的两种集合类型是键值对类型的集合。
<property name="addressList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</property>
<property name="addressMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="USA"/>
</map>
</property>
这个props可以用来设置数据库的配置,而这个配置是一个Properties的类。
<property name="addressProp">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
注入null和特殊符号的值
<property name="email"><null/></property>
<![CDATA[K]]>,里面的K会被认为是纯文本。
ref是引用属性,在配置文件中用的很多。
bean自动装备 autowire属性
byName byType
自动装配有很大的局限性,就是如果用了自动装配,全部的类都要用,而且一个配置文件只能有一个类的bean。
使用外部配置文件属性
创建一个属性文件 .properties文件。用name=value的方式写配置文件。
把属性文件导入bean配置文件,加入命名空间后,用标签
<context: property-placeholder location=” classpath: 路径”/>
在bean配置文件用${ name }的方式访问配置文件的数据。
SpEL
#号做定界符,#{ },字符串需要引号。
引用类的静态属性 #{T (java.lang.Math).PI }
可以直接引用bean或者其属性 #{id |id.property}
可以在#{ }内用表达式。
bean的生命周期
通过构造器或工厂方法创建bean的实例,为bean设置属性或引用,调用bean的初始化方法,使用bean,容器关闭时,调用bean的销毁方法。
用init-method destroy-method可以为bean设置相应的方法。
bean的后置处理器,在初始化前后执行,实现beanpostProcess接口。
postProcessBeforeInitialization方法
postProcessAfterInitialization方法
这个两个方法的参数bean ,beanName解读,bean是bean的实例本身,beanName是IOC容器配置bean的名字。
可以修改返回的bean,甚至返回一个新的bean实例,及用new创建的类。
静态工厂方法创建bean实例,class属性指向静态工厂方法的全类名。
factory-method指向静态工厂方法的名字
constructor-arg向静态工厂方法传递参数。
不创建StaticCarFactory,通过静态工厂方法,返回bean实例。
通过实例工厂方法创建bean,及实例工厂方法需要创建工厂bean。
factory-bean属性指向工厂ID,其他同上。
FactoryBean配置Bean
1 实现一个类实现FactoryBean<>接口
2 配置文件里配置bean的属性,property属性是配置factorybean的属性,但返回的类型是getObject的实例。
spring注解
@Component基本组件,spring管理组件
@Repository标识持久层组件
@service 业务层组件
@controller表现层组件
<context : component-scan base-package=” “></……>扫描@componet注解的包以及子包和包含注解的类。让他们自动装入IOC容器内。
@Required 注释
注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
@Autowired 注释
在类的属性或者属性的setter方法前注释,会实现自动装配,在属性前注入,可以消去setter方法。
构造器前也可以用。
@Autowired 的(required=false)选项
@Qualifier 注释
可能会有这样一种情况,当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱。
@Configuration 和 @Bean 注解
带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。最简单可行的 @Configuration 类如下所示:
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
上面的代码将等同于下面的 XML 配置:
<beans>
<bean id="helloWorld" class="com.tutorialspoint.HelloWorld" />
</beans>
带有 @Bean 注解的方法名称作为 bean 的 ID,它创建并返回实际的 bean。你的配置类可以声明多个 @Bean。一旦定义了配置类,你就可以使用 AnnotationConfigApplicationContext 来加载并把他们提供给 Spring 容器,如下所示:
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}