Spring学习总结
spring是什么?
spring是Java EE编程领域中的一个轻量级开源框架,它是为了解决企业级编程开发中的复杂性,实现敏捷开发的应用型框架,它集成各类型的工具,通过核心的Bean factory实现了底层的类的实例化和生命周期的管理。
在整个容器中,各类型的功能被抽象成为了一个个的Bean,这样就可以实现各种功能的管理,包括动态加载和切面编程。
Spring为了降低Java开发的复杂性,采用了以下四种策略:
- 基于PoJo的轻量级和最小侵入式编程
- 通过依赖注入和面向切面实现松耦合
- 基于切面和惯例进行声明式编程
- 通过切面和模板减少样版式代码
IoC容器
IoC控制反转是一种设计思想,DI依赖注入是实现IoC的一种方式,在有IoC的程序中,对象的创建由自己控制,控制反转后将对象的创建转移给了第三方。
通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。
Spring容器在初始化时会先读取配置文件,根据配置文件或者元数据创建与组织对象存入容器中,程序使用时,再从IoC容器中取出需要的对象。
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。Bean是由Spring IoC容器实例化,组装和管理的对象,而Bean与IoC之间的依赖关系反映在对bean的配置中。
BeanFactory以及ApplicationContext提供了一种高级配置机制,能够管理任何类型的对象。他们两个的区别即为后者是前者的子接口,ApplicationContext增加了更多针对企业的功能。ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常不建议使用BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。
Spring配置元数据
Spring IoC 容器完全由实际编写的配置元数据的格式解耦。有三种方式把配置元数据提供给 Spring 容器:
-
基于 XML 的配置文件
-
基于注解的配置
- 基于 Java 的配置
spring Bean的作用域
Spring 框架支持以下五个作用域,分别为 singleton、prototype、request、session 和 global session
singleton:即单例,在spring IoC容器中只有一个Bean实例,为默认值。在创建容器时,会自动创建Bean对象,不管你是否使用。
prototype:在容器中每次调用Bean时,都会创建一个Bean实例,每次调用getBean()方法都相当于new一个Bean对象。
Prototype 是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。
request:每次请求都会创建一个Bean实例,该作用域仅适用于WebApplicationContext环境下。
session:同一个session共享同一个Bean,不同的session使用不同的Bean,也仅限于WebApplicationContext环境下。
global session:一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境。
Bean的生命周期:
Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁
想要你要注册关闭 hook时可以在方法中注册一个在 AbstractApplicationContext 类中声明的关闭 hook 的 registerShutdownHook() 方法。它将确保正常关闭,并且调用相关的 destroy 方法。再在对应的xml配置文件中设置destroy-method="xxx"。
spring依赖注入:
1.基于构造函数的依赖注入
使用<constructor-arg>元素,具体看构造函数的参数列表,如果为基本数据类型或者String 可以使用type方式注入或者使用index传入对象参数列表的值,如果参数为一个类,需要构造那个类的Bean,用ref传入那个Bean的id。
2.基于set方法的依赖注入
使用<property>元素
3.注入内部Bean
在Bean中的对应<property>元素中间嵌套该Bean
4.注入集合
如果想传递多个值,如java Collecction类型的List,Map,Set或者Properties可以使用Spring提供的4种集合的配置元素:
1.<list>:注入一列值,允许重复。
2.<set>:注入一列值,不允许重复
3.<map>:注入名称键值对集合,其中名称和值可以是任何类型
4.<properties>:注入名称键值对集合,其中名称和值都是字符串类型
注入null:不写value="xxx"直接在<porpertiy>中嵌套一个<null/>即可注入空值。
注入空字符串:将value置为"",相当于exampleBean.setXXX("");
Spring Beans自动装配
Spring 容器可以在不使用<constructor-arg>
和<property>
元素的情况下自动装配相互协作的 bean 之间的关系,这有助于减少编写一个大的基于 Spring 的应用程序的 XML 配置的数量。
自动装配模式:使用<bean>
元素的 autowire 属性为一个 bean 定义指定自动装配模式,它们可用于指示 Spring 容器为来使用自动装配进行依赖注入。
no:不开启自动装配,不指定autowire的默认值。
byName:由属性名自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byName。然后尝试匹配,并且将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
例如:在配置文件中,如果一个 bean 定义设置为自动装配 byName,并且它包含xx属性(即,它有一个 xx(...) 方法),那么 Spring 就会查找定义名为 xx 的 bean,并且用它来设置这个属性。
byType:由属性数据类型自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byType。然后如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。
例如,在配置文件中,如果一个 bean
定义设置为自动装配 byType
,并且它包含XX类型的属性,那么 Spring
就会查找定义名为XX 的 bean
,并且用它来设置这个属性。你仍然可以使用 <property
> 标签连接其余属性。
constructor:类似于byType,该类型适用于构造函数参数类型,如果容器中没有一个构造函数参数类型的bean,则一个致命错误将会发生。
例如:在配置文件中,如果一个 bean 定义设置为通过构造函数自动装配,而且它有一个带有XX类型的参数之一的构造函数,那么 Spring 就会查找定义名为XX的 bean,并用它来设置构造函数的参数。你仍然可以使用 <constructor-arg> 标签连接其余属性。
Spring基于注解的配置
从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。
注解连线在默认情况下在 Spring 容器中不打开。需要使用 <context:annotation-config/>来开启注解扫描。
Spring中重要的注解:
1.@Required:它应用于Bean属性中的Set方法上,它代表Set方法中的值必须在xml配置文件进行配置,否则会抛出一个BeanInitializationException 异常。
2.@Autowired:将 Spring 容器中的 bean 自动的和我们需要这个bean的类组装在一起。它经常和@Qualifier一起使用在使用@Autowired时,首先在容器中查询对应类型的bean。如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据。如果查询的结果不止一个,那么@Autowired会根据名称来查找。如果查询的结果为空,那么会抛出异常。解决方法时,使用required=false。如果查询结果为多个,可以在@Autowired下添加一个@Quailifer来指定要查找Bean的名称。
3.@Configuration 和 @Bean 注解
带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。
Aop
为了使用Aop命名空间,需要在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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> </beans>
还需要导入aspectjweaver.jar包或者在Maven中导入
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
1.定义一个切面aspect,使用ref方式注入Bean
<aop:config> <aop:aspect id="aspect" ref="xxx"> ... </aop:aspect> </aop:config> <bean id="xxx" class="...">
2.定义一个切点
如:
<aop:config> <aop:aspect id="aspect" ref="xxx"> <aop:pointcut id="pointCut" expression="execution(* com.xx.xx.xx.*.*(..))"/> ... </aop:aspect> </aop:config> <bean id="aBean" class="...">
其中execution表达式格式为( "execution(返回值 空格 包名.类名.方法名.(参数列表 ..代表任意参数))")其中还可以在头加上访问修饰符 最后可以加上异常模式 这两个是可选项。
3.aop:advice
共5种:
1.aop:before:前置增强
2.aop:after:后置增强
3.aop:around:环绕增强
4.aop:after-returning:正常返回增强
5.aop:after-throwing:异常返回增强
它们的执行顺序为around before先执行然后是before,方法,around after ,after,最后判断使用aop:after-returning还是after-throwing。
基于 AOP 的 @AspectJ
使用@Aspect可以定义一个类为Aspects类
使用@PointCut("exacution表达式")定义一个方法为切点,该方法等价于切点
使用@Before("切点"),@After("切点"),@Around("切点"),@
Spring事务控制
Spring事务控制分为编程式事务控制和声明式事务控制
事务的概念可以描绘成下面4个方面,即ACID
原子性:事务应该当作一个单独单元的操作,这意味着整个序列操作要么是成功,要么是失败的。
一致性:这表示数据库引用完整性的一致性,表中唯一的主键等。
隔离性:可能同时处理很多有相同的数据集的操作,每个事务应与其他事务隔离,防止数据损坏
持久性:一旦一个事务完成全部操作,这个事务的结果必须是永久性的,不能因为系统故障而从数据库删除。
Spring的编程式事务控制:需要有一个带有适当的 transaction 属性的 TransactionDefinition的实例,通过它的getTransaction() 方法返回一个TransactionStatus实例。如果没有错误可以通过PlatformTransactionManager 的 commit() 方法来提交这个事务,否则的话,你可以使用 rollback() 方法来回滚整个操作。
Spring的编程式事务控制:在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:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="create"/> </tx:attributes> </tx:advice> ...
并通过Aop方式将事务控制织入到执行sql中的方法中,如:
<aop:config> <aop:pointcut id="createOperation" expression="execution(* com.tutorialspoint.StudentJDBCTemplate.create(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="createOperation"/> </aop:config>
这样就可以实现对事务的控制了。