Spring
2019-02-28 09:54:57 69 举报
AI智能生成
但是
作者其他创作
大纲/内容
分支主题
SPRING
MyBatis
MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal0MyBatis 本是apachefont face=\"宋体\
MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal0MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal0Jdbc问题总结
MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal01、 数据库连接频繁开启和关闭,会严重影响数据库的性能。
MicrosoftInternetExplorer402DocumentNotSpecified7.8 磅Normal02、 代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。
mapper代理
1、mapper接口的类名的全限定名和mapper映射文件的namespace值一致。2、mapper接口的方法名称要和mapper映射文件的statement的id一致。3、mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致。4、mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致。
作用域和生命周期
SqlSessionFactoryBuilder
这个类可以在任何时候被实例化、使用和销毁。一旦您创造了SqlSessionFactory 就不需要再保留它了。所以SqlSessionFactoryBuilder 实例的最好的作用域是方法体内(即一个本地方法变量)。您能重用SqlSessionFactoryBuilder 创建多个SqlSessionFactory 实例,但最好不要把\t时间、资源放在解析XML 文件上,而是要从中解放出来做最重要事情。
SqlSessionFactory
一旦创建,SqlSessionFactory 将会存在于您的应用程序整个运行生命周期中。很少或根本没有理由去销毁它或重新创建它。最佳实践是不要在一个应用中多次创建SqlSessionFactory。\t\t这样做会被视为“没品味”。所是SqlSessionFactory 最好的作用域范围是一个应用的生命周期范围。这可以由多种方式来实现,最简单的方式是使用Singleton 模式或静态Singleton 模式。\t\t但这不是被广泛接受的最佳做法,相反,您可能更愿意使用像Google Guice 或Spring 的依赖注入方式。这些框架允许您创造一个管理器,用于管理SqlSessionFactory 的生命周期。
SqlSession
每个线程都有一个SqlSession 实例,SqlSession 实例是不被共享的,并且不是线程安全的。因此最好的作用域是request 或者method。决不要用一个静态字段或者一个类的实例字段来保存SqlSession 实例引用。也不要用任何一个管理作用域,如Servlet 框架中的HttpSession,来保存SqlSession 的引用。如果您正在用一个WEB 框架,可以把SqlSession 的作用域看作类似于HTTP 的请求范围。也就是说,在收到一个HTTP 请求,您可以打开一个SqlSession,当您把response 返回时,就可以把SqlSession 关闭。关闭会话是非常重要的,您应该要确保会话在一个finally 块中被关闭。
Mapper 实例
Mappers 是创建来绑定映射语句的接口,该Mapper 实例是从SqlSession 得到的。因此,所有mapper 实例的作用域跟创建它的SqlSession 一样。但是,mapper 实例最好的作用域是method,也就是它们应该在方法内被调用,使用完即被销毁。并且mapper 实例不用显式地被关闭。虽然把mapper 实例保持在一个request 范围(与SqlSession 相似)不会产生太大的问题,\t但是您可能会发现,在这个层次上管理太多资源可能会失控。保持简单,就是让Mappers 保持在一个方法内。
Setting
cacheEnabled
全局性地启用或禁用所有在mapper 配\t\t\t置文件中配置的缓存。\t\t\ttrue |\t\t\tfalse\t\t\ttrue
lazyLoadingEnabled
全局性地启用或禁用延迟加载。当禁用\t\t\t时,所有关联的配置都会立即加载。\t\t\ttrue |\t\t\tfalse\t\t\ttrue
aggressiveLazyLoading
当启用后,一个有延迟加载属性的对象\t\t\t的任何一个延迟属性被加载时,该对象\t\t\t的所有的属性都会被加载。否则,所有\t\t\t属性都是按需加载。\t\t\ttrue |\t\t\tfalse\t\t\ttrue
multipleResultSetsEnabled
允许或禁止从单一的语句返回多个结果\t\t\t集(需要驱动程序兼容)。\t\t\ttrue |\t\t\tfalse\t\t\ttrue
useColumnLabel
使用列的标签而不是列的名称。在这方\t\t\t面,不同的驱动程序可能有不同的实\t\t\t现。参考驱动程序的文档或者进行测试\t\t\t来确定您所使用的驱动程的行为\t\t\ttrue |\t\t\tfalse\t\t\ttrue
useGeneratedKeys
允许JDBC 自动生成主键。需要驱动程\t\t\t序兼容。如果设置为true 则会强行自\t\t\t动生成主键,然而有些则不会自动生成\t\t\t主键(驱动程序不兼容),但依旧会工\t\t\t作(如Derby)。\t\t\ttrue |\t\t\tfalse\t\t\tFalse
autoMappingBehavior
defaultExecutorType
配置默认的执行器(executor)。\t\t\tSIMPLE :简单的执行器。\t\t\tREUSE :重用prepared statements 的\t\t\t执行器。\t\t\tBATCH:重用statements 并且进行批量\t\t\t更新的执行器。\t\t\tSIMPLE\t\t\tREUSE\t\t\tBATCH\t\t\tSIMPLE
defaultStatementTimeout
设置查询数据库超时时间。任何正整数Not Set\t\t\t(null)
完整配置例子
类型处理器
\t每当MyBatis 设置参数到PreparedStatement 或者从ResultSet 结果集中取得值时,就会使\t用TypeHandler 来处理数据库类型与java 类型之间转换。
重写类型处理器
能够重写类型处理器(type handlers),或者创建您自己的类型处理器去处理没有被支持\t\t\t的或非标准的类型。要做到这一点,只要实现TypeHandler 接口(org.mybatis.type),并且将您\t\t\t的TypeHandler 类映射到java 类型和可选的JDBC 类型即可。
配置文件
\t使用上面的TypeHandler 将会重写已经存在的用来处理java 的String 属性、VARCHAR 参数\t和结果集的类型处理器。注意,MyBatis 并不会通过数据库的元数据来确认类型,所以您必须指\t定它的一个类型处理器,用于将VARCHAR 字段的参数和结果映射到正确的类型上。这是因为\tMyBatis 在语句的执行之前都不知道它要处理的数据类型是什么。
逆向工程
http://blog.csdn.net/biandous/article/details/65630783
DBCP使用
配置事物
事物的传播属性
定义
当事物方法被另一个事物方法调用时,必须指定事物应该如何传播,例如:方法可能继续在现有事物中运行,也可能开启一个新事物,并在自己的事物中运行
事物的传播行为可以由传播属性指定Spring定义7中传播行为
事物传播属性可以在@Transactional注解的propagation属性中定义
七种传播行为
REQUIRED
如果有事务在运行,当前的方法在这个事务内运行,否则,就启动一个新的事务,并在自己的事务内运行
当bookService的purchase()方法被另一个事物方法checkout()调用时,它默认在现有的事务内运行,这个默认的传播行为就是REQUIRED。因此在方法开始和终止边界内只有一个事务,这个事务只在checkout()方法结束的时候被提交。
REQUIRED_NEW
当前的方法必须启动新事物,并在它自己的事务内运行,如果有事务正在运行,应该将他挂起
SUPPORTS
如果有事务在运行,当前的方法就在这个事务内运行。否则它可以不运行在事务中
NOT_SUPPORTS
当前的方法不应该运行在事务中,如果有运行的事务,将他挂起
MANDATORY
当前的方法必须运行在事务内部,如果没有正在运行的事务,就抛出异常
NEVER
当前的方法不应该运行在事务中,如果有运行的事务,就抛出异常
NESTED
如果有事务在运作,当前的方法就应该在这个事务的嵌套事务内运行。否则,就启动一个新的事务,并在它自己的事务内运行
事务的隔离级别
当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发运行时,可能会出现许多意外的问题
并发事务所导致的问题可以分为3种类型
脏读
不可重复读
对于两个事务T1,T2, T1读取了一个字段,然后T2更新了该字段,之后,T1再次读取同一个字段,值就不同了
幻读
对于两个事务T1,T2 T1从一个表中读取了一个字段,然后T2在该表中插入了一些新的行,之后,如果T1再次读取同一个表,就会多出几行
事务隔离级别
DEFAULT
使用底层数据库的默认隔离级别,对于大多数数据库来说默认隔离级别都是READ_COMMITED
READ_UNCOMMITTED
允许事务读取未被其他事务提交的变更,脏读,不可重复读和幻读问题都会出现保证了读取过程中不会读取到非法数据。
READ_COMMITED
只允许事务读取已经被其他事务提交的变更,可以避免脏读,但不可重复读和幻读问题仍可能出现大多数主流数据库的默认事务等级,保证了一个事务不会读到另一个并行事务已修改但未提交的数据,避免了“脏读取”。该级别适用于大多数系统。
REPEATABLE_READ
确保事务可以多次从一个 字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新,可以避免脏读和不可重复读,但幻读问题仍然存在保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据。避免了“脏读取”和“不可重复读取”的情况,但是带来了更多的性能损失。
SERIALIZABLE
确保事务可以从一个表中读取相同的行,这个事务持续期间,禁止其他事务对该表进行插入,更新和删除操作,所有并发问题都可以避免,但性能十分低下最严格的级别,事务串行执行,资源消耗最大;
设置
用@Transactional注解声明式地管理事务时,可以在@Transactional的isolation属性中设置隔离级别
在Spring 2.x事务通知中,可以在<tx:method>元素中指定隔离级别
补充
事务的隔离级别要得到底层数据库引擎的支持,而不是应用程序或者框架的支持
Mysql支持4种事务隔离级别
从理论上来说,事务应该彼此完全隔离,以避免并发事务所导致的问题,然而,那样会对性能产生极大的影响,因为事务必须按顺序运行在实际开发中,为了提升性能,事务会以较低的隔离级别运行事务的隔离级别可以通过隔离事务属性指定
设置回滚事务属性
默认情况下只有未检查异常(RuntimeException和Error类型的异常)会导致事务回滚。而受检查异常不会
事务的回滚规则可以通过@Transactional注解的rollbackFor好noRollback属性来定义,这两个属性被声明为Class[]类型的,因此可以为这两个属性指定多个异常类rollbackFor:遇到时必须进行回滚noRollbackFor:一组异常类,遇到时必须不回滚
在Spring 2.x事务通知中,可以在<tx:method>元素中指定回滚规则,如果有不止一种异常,用逗号分隔
设置超时属性
由于事务可以在行和表上获得锁,因此长事务会占用资源,并对整体性产生影响
超时事务属性:事务在强制回滚之前可以保持多久,这样可以防止长期运行的事务占用资源
设置只读属性
如果一个事务只读取数据但不做修改,数据库引擎可以对这个事务进行优化
表示这个事务只读取数据但不更新数据,这样可以帮助数据库引擎优化事务
spring
IOC
IOC(Inversion of Control)控制反转
其思想是反转资源获取的方向。传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适时返回资源,而应用了IOC之后,则是容器主动将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接收资源,这种行为也被称为查找被动形式。
DI(Dependency Injection)依赖注入
IOC的另一种表达形式,即组件以一些预先定义好的方式(例如:setter方法)接收来自如容器的资源注入。相对于IOC而言,这种表达更直接
Spring支持3种依赖注入的方式
属性注入
属性注入即通过setter方法注入Bean的属性值或依赖的对象
属性注入使用<property>元素,使用name属性指定Bean的属性名称,value属性或<value>子节点指定属性值
属性注入是实际应用中最常用的注入方式
构造器注入
通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化后就可以使用。
构造器注入在<constructor-arg>元素里声明属性,<constructor-arg>中没有name属性
工厂方法注入(很少使用,不推荐)
字面值
可用字符串表示的值,可以通过<value>元素标签或value属性进行注入
基本数据类型及其封装类、String等类型都可以采取字面值注入的方式
若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来
spring容器
在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行实例化,只有在容器实例化后,才可以从IOC容器里获取Bean实例并使用
Spring提供了两种类型的IOC容器实现
BeanFactory(IOC容器的基本实现)
BeanFactory是Spring框架的基础设施,面向Spring本身;
ApplicationContext(提供了更多的高级特性,是BeanFactory的子接口)
ApplicationContext面向使用Spring框架的开发者,
几乎所有的应用场合都直接使用ApplicationContext而非底层的BeanFactory无论使用何种方式,配置方式相同
ApplicationContext的主要实现类
主要实现类
ClassPathXmlApplicationContext
从类路径下加载配置文件
ApplicationContext在初始化上下文时就实例化所有单例的Bean
WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
FileSystemXmlApplicationContext
从文件系统中加载配置文件
bean
配置Bean
反射配置
命名空间(p)
简化xml文件的配置
Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置bean的属性
代码
集合属性
通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签,每个条目包含一个键和一个值
必须在<key>标签定义键
可以将Map的键和值作为<entry>的属性定义:简单常量使用key和value来定义;bean引用通过key-ref和value-ref属性定义
使用utility scheme定义集合
使用基本的集合标签定义集合时,不能将集合作为独立的ben定义,导致其他bean无法引用该集合,所以无法在不同bean之间共享集合
自动装配(autowrie)
三种方式
Spring IOC容器可以自动装配bean需要做的仅仅是在<bean>的autowire属性里指定自动装配的模式
byType(根据类型自动装配):若IOC容器中有多个与目标bean类型一致的bean,在这种情况下,spring将无法判定哪个bean最合适该属性,所以不能执行自动装配
byName(根据名称自动装配):必须将目标bean的名称和属性名设置完全相同
constructor(通过构造器自动装配:当bean中存在多个构造器时,此种自动装配方式将会很复杂,不建议使用)
缺点
一般情况下,在实际的项目中很少使用自动装配功能,因为和自动装配功能所带来的好处比起来,明确清晰的配置文档更有说服力一些
工厂方法配置
静态
实例
将对象的创建过程封装到另外一个对象的实例方法里。当客户需要请求对象时,只需要简单的调用该实例方法而不需要关心对象的创建细节
要声明通过实例工厂方法创建的 Bean在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean在 factory-method 属性里指定该工厂方法的名称使用 construtor-arg 元素为工厂方法传递方法参数
FactoryBean
注解配置
子主题
扫描组件
当在组件类上使用了特定的 注解之后,还需要在Spring的配置文件中声明<context:component:scan>
base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里及其子包中的所有类当需要扫描多个包时,可以使用逗号分隔如果仅希望扫描特定的类而非基包下的所有类,可使用resource_pattern属性过滤特定的类<context:include-filter>子节点表示要包含的目标类<context:exclude-filter>子节点表示要排除在外的目标类<context:component-scan>下可以拥有若干个<context:include-filter>和<context:exclude_filter>子节点
过滤子节点支持表达式
组件装配
@Autowired注解
@Resource注解要求提供一个Bean名称的属性,若该属性为空,则自动采用标注的变量或方法名作为bean的名称
@Inject和@Autowired注解一样也是按类型匹配注入的Bean,但没有reqired属性
建议使用@Autowired注解
泛型依赖注入
泛型
引用Bean
引用
组成应用程序的Bean经常需要相互协作以完成应用程序的功能。要使Bean能够互相访问,就必须在Bean配置文件中指定对Bean的引用
在Bean的配置文件中,可以通过<ref>元素或ref属性为Bean的属性或构造参数指定对Bean的引用
当Bean实例仅仅给一个特定的属性使用时,可以将其声明为内部Bean,内部Bean声明直接包含在<property>或<constructor-arg>元素里,不需要设置任何id或name属性
内部bean不能被外部引用
bean直接的关系
继承
子bean从父bean中继承配置,包括bean的属性配置
子bean也可以覆盖父bean继承过来的配置
父bean可以作为配置模板,也可以作为bean实例,若只想把父bean作为模板,可以设置<bean>的abstract属性为true,这样spring将不会实例化这个bean
也可以忽略父bean的class属性,让子bean指定自己的类,而共享相同的配置属性,但此时abstract必须设置为true
若一个bean的class属性没有指定,则该bean必须是一个抽象bean
依赖
Spring允许用户通过depends-on属性设定bean前置依赖的bean,前置依赖的bean会在本bean实例化之前创建好
如果前置依赖于多个bean,则可以通过逗号,空格的方式配置bean名称
bean作用域
在Spring中,可以在<bean>元素的scope属性里设置bean的作用域
默认情况下,Spring只为每个在IOC容器里声明的bean创建唯一的一个实例,整个IOC容器范围内部都能共享该实例。所有后续的getBean调用和bean引用都将返回这个唯一的bean实例,该作用域被称为singleton,它是所有bean的默认作用域
四种作用域
singleton
在SpringIOC容器中仅存在一个Bean实例,bean以单例的方式存在
prototype
每次调用getBean时都会返回一个新的实例
request
每次http请求都会创建一个新的bean,该作用域仅适用于WebpplicationContext环境
session
同一个HTTP Session共享一个Bean,不同的HTTP Sessionn使用不同的Beana.该作用域仅适用于WebApplicationContext环境
外部属性文件
Spring 还允许在属性文件中使用 ${propName},以实现属性之间的相互引用。
spring2.0
Spring 2.5 之后: 可通过 <context:property-placeholder> 元素简化:
SpEL
简介
Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL
SpEL 为 bean 的属性进行动态赋值提供了便利
通过 SpEL 可以实现: 通过 bean 的 id 对 bean 进行引用 调用方法以及引用对象中的属性 计算表达式的值 正则表达式的匹配
字面量的表示
整数:<property name=\"count\" value=\"#{5}\"/>小数:<property name=\"frequency\" value=\"#{89.7}\"/>科学计数法:<property name=\"capacity\" value=\"#{1e4}\"/>String可以使用单引号或者双引号作为字符串的定界符号:<property name=“name” value=\"#{'Chuck'}\"/> 或 <property name='name' value='#{\"Chuck\"}'/>Boolean:<property name=\"enabled\" value=\"#{false}\"/>
支持运算符号
bean的生命周期
Bean 后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理.
整合多个配置文件
Spring允许通过<import>将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动Spring容器时,仅需要指定合并好的配置文件就可以。
import 元素的 resource 属性支持 Spring 的标准的路径资源
AOP
AOP之前存在问题
动态代理解决
AOP术语
切面
横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
通知
切面必须要完成的工作
目标
被通知的对象
代理
向目标对象应用通知之后创建的对象
连接点
程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置
切点
每个类都拥有多个连接点:例如 ArithmethicCalculator 的所有方法实际上都是连接点,即连接点是程序类中客观存在的事务。AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。切点和连接点不是一对一的关系,一个切点匹配多个连接点,切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。
AspectJ
java社区里最完整最流行的AOP框架
Spring启动
声明切面
前置通知
后置通知
返回通知
异常通知
环绕通知
0 条评论
下一页