首页 > 代码库 > Spring

Spring

DI

一 Spring概述

1.什么是Spring?

⑴Spring是为了解决企业应用开发的复杂性而创建的,优秀的轻量级企业应用解决方案,开放源代码,主要特点是采用分层结构,允许单独使用某一模块,也可以将多个模块组合使用。

⑵企业应用:为了满足企业运行需要开发的软件系统,现在的企业应用大多运行在开放性平台(存在信息交互的可能性),不再是孤立的系统,而是在相互联系中构成了一个系统群。

⑶轻量级:轻量级框架如Struts、Spring,侧重于降低开发的复杂度,体积小,消耗小,相应地处理能力有所减弱。

⑷JavaBean:使用java语言编写的可重用组件,主要用作数据的载体。

⑸EJB:EnterpriseJavaBean,服务器端组件模型,定义了一个用于开发基于组件的企业应用的规范,本身复杂而繁琐。

2.Spring的优点:

⑴Spring采用分层结构,每一个模块可以单独使用,也可以联合使用。

3.Spring的技术基础:

⑴IoC:Injectionof Control,控制翻转。

⑵AOP:AspectOriented Program,面向切面编程。

4.Spring的构成:

⑴Springcore:Spring框架的核心,提供了Spring框架的基础功能,实现了IoC,包含重要的类BeanFactory。BeanFactory是IoC的容器,负责bean的实例化、初始化、使用与销毁。

⑵Springcontext:继承了BeanFactory,添加了许多功能,如国际化、数据校验等。

⑶SpringAOP:继承AOP的所用功能,通过事务可以将Spring管理的任意对象AOP化。

⑷SpringDAO:提供了JDBC的抽象层,简化了数据库厂商的异常错误,大幅度减少了代码,并且支持声明式事务与编程式事务。

⑸SpringORM;兼容所有流行的ORM框架,完美地整合了Hibernate。

⑹SpringWeb:提供了Servlet监听器上下文与Web上下文,集成了现有的Web框架,如JSP、Struts。

⑺SpringMVC:建立在Spring的核心功能之上,具有Spring框架的所有特性。

 

二几个比较重要的基础类

1.BeanFactory

一个接口,通过读取XML配置文件中javabean的定义,实现对javabean的创建、使用与管理。

2.XmlBeanFactory

BeanFactoy的一个实现类,通过流行的XML文件格式读取配置信息来加载javabean,具体加载过程:

Resource resource=newClassPathResource("xxxxx");
BeanFactory factory=newXmlBeanFactory(resource);
Objectobj=(Object)factory.getBean("xxxx");

⑴其中Resource是一个接口,ClassPathResource是一个实现类,用于将资源封装成对象。

⑵classpath:代表类路径,因为程序执行最终使用是类文件,从类路径中加载,所以凡是程序运行必需的文件都要放在类路径中。Eclipse作为一种java集成开发工具,会将src目录下的文件自动放到类路径下。

3.ApplicationContext

一个接口,继承了BeanFactory,添加了许多功能,如国际化、数据验证等,有三个比较重要的实现类:

⑴ClassPathXmlApplicationContext:从类路径下加载配置文件,一般常用此类加载applicationContext.xml文件。

⑵FileSystemXmlApplicationContext:从指定路径加载文件,适用性范围广。

⑶WebApplicationContext:Spring与Web整合后在Web中的容器。

 

三依赖注入

1.IoC:控制反转

一种思想,依赖注入是该思想的一种事项,将创建实例的任务交给IoC容器,需要实例时向容器发送请求即可,这样降低了引用类A对被引用类B的依赖,即B发生改变,A需要修改很少一部分,甚至不需要修改。

2.IoC降低耦合度的实现过程

⑴在传统开发中,A类调用B类,就必须在内部创建B类,B b= new B(),当B类被删除,就需要修改A类的代码,这样A类就受到B类变化的拖累。而如果A类调用的是B类的接口,并且实例对象由外部创建,当外部实现类发生改变时,只要提供一个满足要求的实现类,A依然可以正常运行,不需要修改A中的代码,B的变化没有波及A。

⑵IoC降低耦合度是在对象创建过程实现的。

3.依赖注入

⑴IoC容器将A对象依赖的B对象注入到A中,叫做依赖注入。

⑵依赖注入的几种方式:

①setter注入:底层通过调用A中的setter方法将B注入。

配置文件的编写:

<bean  id="引用变量"class="全限定性类名">
        <property  name="属性名">
                  <value>属性值</value>
        </property>
</bean>

⑵构造器注入:底层通过调用构造方法将依赖注入。

配置文件的编写:

1 <bean  id="引用变量"class="全限定性类名">
2       <constructor-arg>
3                  <value>参数值</value>
4       </constructor-arg>
5 </bean>

①使用构造器注入,配置文件中标签的赋值顺序必须与构造方法形参定义顺序一致,否则抛出出错。为了避免顺序不一致导致的错误,在配置文件中为每一个赋值标签设定一个index值,对应其要赋值的形参在构造器中的顺序:

1 <constructor-arg index="0">
2            <value>参数值</value>
3 <constructor-arg>

②类中要有对应的构造方法。

⑶当属性为集合时在配置文件中设定初始值的方法为:

①数组与List集合: 

1 <list>
2      <value>value01</value>
4      <value>value02</value>
5 </list>

数组还有一种更简单的赋值方式,值写在一块,用逗号隔开:

1 <property name=""value="value01,value02"/>

②Set集合:

1 <set>
2     <value>value01</value>
3     <value>value02</value>
4 </set>

③Map集合:

 <map>
2     <entry  key=""value=""/>
3     <entry  key=""value=""/>
4 </map>

④Properties对象:  

1  <props>
3       <prop  key="xxx"></prop>
5       <prop  key="xxx"></prop>
7 </props>

4.引用同一配置文件中其他的bean   

<property name="">
            <ref   local="id"/>
</property>

 

5.自动装配

⑴将一个bean调用的另一个bean自动转配到该bean中,通过<bean>标签的属性autowire实现。

⑵几种常用的自动装配方式

①byName:通过名称装配,将IoC容器中与属性名同名的bean注入。

配置文件编写:

<beanautowire="byName"id=""class=""/>

按名称装配的不足:如果IoC容器中存在多个同名而类型不同的bean,注入后就会发生错误。

②byType:将与属性相同的bean注入。

配置文件编写:

<beanautowire="byType"id=""class=""/>

按类型转配的不足:如果IoC容器中存在多个类型相同的bean,IoC容器会因为无法识别需要的bean而报错。

 

四内部bean

如果希望内部bean只能通过外部bean访问,那么将内部bean的定义放在外部bean内部:

<bean  id="xxx"class="OuterClass">
       <property  name="innerClassAttrName">
               <bean  class="InnerClass">//因为不支持外部对象引用,所以不需要定义id
                         <property  name="">xxxxx</property>
               </bean>
       </property>
</bean>

 

五同类抽象bean与异类抽象bean

1.产生的背景

在配置文件中,如果多个bean拥有共同的属性,分别为每一个bean配置这些共同的属性,数据冗余,为了消除冗余,将这些共同的属性提取出来,定义在一个抽象bean中,其他bean通过引用该抽象bean为属性赋值。抽象bean集中了共同属性,统一赋值。

2.同类抽象bean

⑴适用于为同类的bean赋值。

⑵配置文件编写:

<bean  id="abstractBean"class="ClassA"abstract="true">
          <property  name=""value=""/>
            ........为共同属性赋值..........
</bean>
<bean  id="xxx"parent="abstractBean">
          <property  name=""value=""/>
             ........为特有属性赋值..........
</bean>

abstract="true":将该bean定义为抽象bean,以避免直接使用该bean,即定义为抽象以后,通过getBean无法访问该bean。

3.异类抽象bean:

⑴适用于为不同类型的bean赋值。、

⑵配置文件编写:

<bean  id="abstractBean"abstract="true">
           <property  name=""value=""/>
            ........为共同属性赋值..........
</bean>
<bean  id="xxx"class=""parent="abstractBean">
           <property  name=""value=""/>
            ........为特有属性赋值..........
</bean>

 

六 bean作用域

1.bean:Spring中的bean就是由Spring创建、装配与管理的对象。

2.作用域的不同,bean的管理者与生命周期不同。

3.生命周期的设定

⑴第一种方式:<bean  id=""class=""/>:采用默认值singleton。

⑵第二种方式:<bean  id=""class=""singleton="true/false"/>。

⑶第三种方式:<bean  id=""class=""scope="singleton/prototype"/>。

4.不同作用域介绍:

⑴singleton:bean采用单例模式,对bean的请求返回的是同一bean对象,生命周期与IoC容器相同,由IoC容器管理。

⑵prototype:采用多例模式,每一次请求获取的都是不同的bean对象,IoC容器将对象交给使用者,由使用者管理。

 

七 SpEL

1.Spring  Expression Language,用于在配置文件中动态地为属性赋值,只赋值一次,该值可以来源于容器中其他bean的属性,调用bean方法的返回值,也可是调用容器以外其他类静态方法的返回值。

2.SpEL表达式只在初始化阶段为属性赋值,一旦初始化完成,表达式失效,即只是将beanA在配置文件的属性值传递给beanB的属性,并不是动态地保证beanB的属性值始终与beanA的属性值相同。这一点也可以从配置文件的功能来考虑,配置文件就是用来在初始化阶段为属性赋值,一旦初始化完毕,配置文件的任务就完成了,后续不再发挥作用。

3.基本语法格式:#{}。

4.调用容器中其他bean的属性:#{beanName.attrName}。

5.调用容器中bean的方法:#{beanId.method(arg)}。

6.调用容器以外其他类的静态方法:#{T(全限定性类名).method(arg)}。

7.在配置文件中的使用:<property  name="xxxx"value="http://www.mamicode.com/#{xxxx}"/>,或者

<property  name="xxxx">
        <value>#{xxxx}</value>
</property>

 

八 bean的生命周期

1.不同作用域的bean生命周期不同

⑴singleton:作用域范围singleton的bean生命周期与IoC容器的生命周期相同,容器初始化时创建,容器销毁时销毁。

⑵prototype:作用域范围prototype的bean由容器创建提交给请求方,生命周期由请求方负责。如果请求方不销毁,bean不会一直存在。

2.bean的生命周期可分为11个阶段,即总共有11时机可以用来改变bean。除自定义的BeanPostProcessor适用于所有bean而单独创建外,其他的都通过bean实现相应的接口实现,如BeanNameAware\BeanFactoryAware

\InitializingBean\DisposableBean等。

3.与生命周期相关的接口或者类

⑴在bean内部自定义控制生命周期的方法

①定义在setter方法执行完毕后调用的方法,即初始化完毕之后,该方法必须无参,在配置文件中配置:

<bean  init-method="方法名">。

②定义在IoC容器关闭以后调用的方法,必须无参,在配置文件中配置<bean destory-method="方法名"/>

⑵BeanPostProcessor

①一个接口,其实现类只有在配置文件中配置之后才可以使用,由底层调用,配置时无需设定id。

②容器中所有的bean在初始化阶段都会调用其中的两个方法:

postProcessBeforeInitialization:在bean初始化完毕之前由容器调用;

postProcessAfterInitialization:在bean初始化完毕之后由容器调用。

 

九配置文件的分散编写

1.一个项目通常由一个团队的多个成员合作开发,如果在开发阶段共用一个配置文件,不仅降低了效率,而且不同的人共同操作,还容易发生错误,这是就需要允许多个配置文件的存在,而Spring正好提供了对多个配置文件的支持。

2.平等关系的配置文件:

⑴两个配置文件各自单独存在,不存在包含关系。

⑵在java代码中读取平等关系的配置文件需要使用指定类的可变参数的形式:

new  ClassPathXmlApplicationContext(String...)

3.包含关系的配置文件:

⑴一个配置文件在形式上包含另一个配置文件,通过在配置文件中加入如下内容包含其他配置文件,读取该配置文件即可:

<import   resources="classpath:xxxxx.xml"/>

①在配置文件路径前一定要加classpath,为底层指定加载方式,因为配置文件的加载方法有多种,以ClassPath开头的类从类路径加载,而以FileSystem开头的类从文件路径加载,在java中加载时使用ClassPath开头的类实际上已经设定了文件的加载方法。因为程序员只负责加载外层文件,内层文件的加载是由底层负责的,如果不指明加载方式,底层无法加载,底层执行过程大致是:提取classpath,然后进行判断,根据判断结果选择加载方式,如果classpath不存在,底层就无法进行判断,无法运行,就会抛出错误。

②classpath是一个单词,path的首字母不能大写。

 

十注解

1.注解是注册的一种,可以取代在配置文件中的配置。

2.注解的优点

在java源文件中直接注册,不需要编写配置文件,比较方便,而且标注在类中,可以清楚地看到注释与类的关系。

3.在配置文件头加入context约束,因为要使用<context>标签,只有该约束中有。

4.注解需要在配置文件中添加<context:component-scanbase-package="xxx"/>,注册扫描器,因为Spring不同于Hibernate与Struts,没有默认的配置文件,被动加载,必须显式指明配置文件,因此当采用注解开始时也必须显式
指明组件位置。

⑴如果包名为xxx,表示扫描该包及其子包;

⑵如果包名为xxx.*,表示只扫描子包。

5.常用注释:

⑴@Component(value="http://www.mamicode.com/相当于配置文件中的id"):表明该类是一个组件,扫描时容器会创建该类的实例,这是bean注解的第一步,先让容器把该类当做需要创建bean的类。

⑵@Scope(value="http://www.mamicode.com/singleton/prototype"):设置作用域。

⑶@Value(value=""):为一般属性赋值。

⑷@Resource(name=""):为域属性赋值。域属性就是自定义类的对象。@Autowired:Spring提供的域属性注入注解。

⑸@PostConstruct:在bean内部设定在初始化完成之后调用的方法。初始化完成的标识是InitializingBean实现类的方法afterPropertiesSet调用完毕。

⑹@PreDestroy:在bean内部设定bean销毁前调用的方法。

 

十一 SpringJUnit4

1.SpringJUnit4提供了对bean的简化测试方案,进行简单设置之后,测试bean时就不需要在创建容器,可以直接使用bean。

2.实现

⑴在类上加@RunWith(SpringJUnit4ClassRunner.class):表示采用SpringJUnit4进行测试。

⑵在类上加@ContextConfiguration(locations="classpath:xxxx.xml"):指明配置文件。

⑶在域属性加@Autowired:按照类型注入,也可以采用其他方式注入。因为并不是所有的域属性都是bean,有的可能是测试类新建的。

⑷然后在测试类方法中就可以直接使用bean了。

 

十二只有在对象由Spring容器创建时,属性与引用的其他的bean才会被注入对象中。在程序手动创建时,容器不会对对象施加任何作用。

 


 

AOP

 

一概述

1.Aspect Oriented Program,面向切面编程,一种编程思想,建立在动态代理机制之上。

2.产生背景

⑴在AOP产生以前,OOP是编程的基本原则,所有对象执行需要的代码都必须写在类中。如果多个类拥有一部分相同的代码,那么这些代码就必须在每个类中都编写,不仅代码大量重复,而且不便于维护,这时就产生了将那些重复出现、与业务无关的代码从业务中分离出来的思想,就是AOP。AOP将重复的、与业务无关的代码从业务中分离处理,业务执行时切入业务中,形式上与业务分离,执行时与业务结合,不仅便于维护,而且降低了业务逻辑部分与非业务逻辑部分的耦合度。

3.简单讲,AOP就是将无关且重复的部分从代码中分离处理,执行时再切入代码中。

4.重要的概念

⑴切面:对象执行过程中切入流程的、与业务逻辑无关的代码。与业务无关、重用度高的代码适合用作切面。在程序中,切面是一个集中了通知的类。

⑵切入点:切面切入流程的点,也是切面注入流程的点,Spring只支持方法类型的切入点,即切面只能在对象方法执行前后切入,不能切入方法内部。

⑶通知:切入点被横切时,所采取的业务逻辑,由通知确定执行那个切面。通知是切面中的方法。

⑷目标对象:切面切入的对象。

⑸织入:将切面功能应用于目标对象的过程。

⑹引用:动态地向目标对象添加属性与方法的过程。

 

二 Spring自身对AOP的实现

1.Spring自身提供了对AOP思想的实现,主要借助内置接口的实现类与配置文件完成。

2.重要的概念

⑴Advice:通知,切入点被横切时采取的处理逻辑,即在切入点前后执行的方法。在Spring中,Advice是一个层级比较高的接口,具体使用的通知都间接实现了该接口。缺点是,一旦定义就对所有方法都起作用。

⑵Advisor:顾问,Advice的装饰者,可以对方法进行筛选,使通知只对选定的方法起作用。常用到的两个实现类:

①NameMatchMethodPointcutAdvisor:列举选定的方法,使通知只对选定的方法有效。

②RegexMethodPointccutAdvisor:通过正则表达式匹配方法。

3.Advice

⑴前置通知:在切点执行前执行,实现MethodBeforeAdvice实现。

⑵后置通知:在切点成功执行后执行,排在环绕通知之后,方法无返回值不可以修改返回值,实现AfterReturningAdvice。

⑶环绕通知:在切点执行前与执行成功后执行,可以修改返回值,实现MethodInterceptor。

⑷异常通知:在切点抛出异常时,执行,实现ThrowsAdvice.

4.Advisor的配置

⑴Advisor是Advice的装饰者,可以为Advice指定方法,因此需要传入Advice与方法,将切点与目标方法绑定。

⑵采用NameMatchMethodPointcutAdvisor:

<bean  id=""class="Advisor的两个实现类其中一个">
       <property name="advice"ref="通知名"/>//装饰的通知
       <property  name="mappedNames"value="方法名"/>//即切点
</bean>

⑶采用RegexMethodPointcutAdvisor:

<property name="advice"ref="通知名" />
<property name="pattern" value="正则表达式,匹配对象时接口的方法" />

5.配置文件的编写

⑴代理通过ProxyFactoryBean类创建,底层执行Proxy.newProxyInstance(),对比底层实现,为该类属性赋值,动态地执行:

<bean  id=""class="xxxxxx.ProxyFactoryBean">
         <property  name="targetName"name=""/>
         <property  name="interceptorNames"value="通知名或顾问名"/>
</bean>

6.基于顾问的自动代理生成器

⑴当有多个目标对象时,使用ProxyFactoryBean创建代理对象时,需要为每一个代理对象编写代理创建过程,而使用DefaultAdvisorProxyCreator,可以自动为目标对象创建代理。因为DefaultAutoProxyCreator底层实现了BeanPostProcessor,由底层自动调用。

⑵配置文件的编写:

<bean  class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

⑶自动代理生成器只对Advisor有效,Advisor封装了方法,任何一个bean调用了该方法都会被增强。切面类型狭窄,目标对象广泛。

7.基于beanName的自动代理生成器

⑴该代理生成器弥补类基于顾问的代理生成器无法选择通知、无法选择目标对象的不足。

⑵配置文件的编写:

<bean  id="proxy"class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
         <property  name="beanNames" value="target" />//选择要代理的对象
         <property  name="interceptorNames" value="methodInterceptor" />//选择切面
</bean>

8.无论是基于顾问的,还是基于beanName的自动代理生成器,都可以同时代理多个目标对象,为了区分被代理的目标对象只能通过目标对象来获取代理对象,这样才能保证一个代理对象指向一个目标对象。

 

三 AspectJ

1.AspectJ是一种独立于Spring框架的AOP思想实现,被Spring框架兼容,切面不需要实现特定的接口,就是普通的POJO类,比Spring提供的AOP更强大、灵活、边界,在实际开发中使用较普遍。

2.在AspectJ代理中,Spring容器充当代理工厂。

3.通过在配置文件中注册的方式实现AOP

<aop:configproxy-target-class="true/false">
      <aop:aspect ref="切面所在类的id">
         ---将切点定义在切面内,对其他切面不可见。也可以将切点定义在切面外,对所有切面可见---
                 <aop:pointcut ref="切点所在类的id" expression="execution(切入点表达式)"/>
                 <aop:before method="方法名"pointcut-ref="切点id"/>
                 <aop:after method="方法名"pointcut-ref="切点id"/>
      </aop:aspect>
</aop:config>

⑴切入点表达式:

①什么是切入点表达式?

用于限制切入点的表达式,与表达式匹配的方法都可以用作切入点

②基本结构:[访问权限] 返回值类型 [全限定性类名] 方法名(..).

():匹配不带参数的方法。

(*):匹配带一个参数的方法。

(..):匹配带任意形式参数或则不带参数的方法。

③切入表达式的构成:

*:代表若干字符;

..:代表多级目录;

+:代表该类及其子类。

⑵<aop:config>:配置AOP的全部信息,包括切面、切点。proxy-target-class指明所用的代理机制,CGLIB,还是基于接口的代理JDK,默认为false,使用基于接口的代理。

⑶<aop:aspect>:配置切面,包含切点前执行的方法、切点后执行的方法、适用的切点等。

⑷<aop:pointcut>:定义切点,Spring只支持方法类型的切点,id属性为该切点指定一个id值,供他处引用,expression="execution(* 方法)"指明用作切点的方法,*必须有,之后跟一个空格。

⑸<aop:before>:指明在切点前执行的方法,pointcut-ref属性指明适用的切点。

⑹<aop:after>:指明在切点后执行的方法,无论切点是否成功执行都会执行,pointcut-ref属性指明适用的切点。

⑺<aop:after-throwing>:在抛出异常后执行。

⑻<aop:after-returningreturning="返回值result">:在返回值之后执行,返回值名必须与方法形参名相同。

⑼<aop:around>:紧贴代理对象方法前后执行,方法必须有返回值,可以修改目标方法的返回值。

①当使用环绕通知时,目标对象的方法只在环绕方法内部被调用后才可以执行,因为环绕通知底层采用MethodInterceptor,而拦截器内部必须显式地调用后面的方法,进程才能推进。

②目标对象的方法可能有返回值,因此环绕通知必须有返回值。

   

四 DAO

1.什么是DAO?

Data Access Object,数据访问对象,封装了一些对数据库进行持久化操作的方法,将持久化操作与一般的业务逻辑分开,便于维护与测试。封装了JDBC、简化了对数据库操作的接口。在实际开发DAO层由两部分构成,一部分是抽象DAO,一部分是其实现,DAO层提供了业务逻辑中可能用到的针对数据库的元操作,业务逻辑通过对DAO实现层方法的组合来操作数据库。

2.数据源

数据的来源,一般指数据库,又称数据连接池,一个数据源之所以成为数据的来源,最基本的是与数据库建立连接,数据库连接四要素。数据源是多用户访问情况下必须配置的,为了提交访问效率与速度。

⑴常用的数据源

①Spring提供的数据源DriverManagerDataSource,在实际开发中很少用到,常用到第三方数据源C3P0、DBCP。

<bean  id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property  name="driverClassName">  <value>com.mysql.jdbc.Driver</value> </property>
       <property  name="url"> <value>jdbc:mysql://localhost:3366/db_spring</value>  </property>
       <property  name="username"> <value>root</value> </property>
       <property  name="password"> <value>123</value> </property>
</bean>

②C3P0数据源:

<bean id="c3p0"class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <property  name="driverClass" value="com.mysql.jdbc.Driver" />
       <property  name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3366/db_spring"/>
       <property  name="user" value="root" />
       <property  name="password" value="123" />
</bean>

③DPCP数据源:

<bean id="dbcp"class="org.apache.commons.dbcp2.BasicDataSource">
      <property  name="driverClassName" value="com.mysql.jdbc.Driver" />
      <property  name="url" value="jdbc:mysql://127.0.0.1:3366/db_spring"/>
      <property  name="username" value="root" />
      <property  name="password" value="123" />
</bean>

3.Spring提供了一些抽象的DAO类:

⑴JdbcDaoSupport:支持以基础的JDBC技术操作数据库的抽象类,开发者需要设置数据源,通过子类获得JdbcTemplate来访问数据库。

①基本原理:利用框架提供的类DriverManagerDataSource创建与数据的连接,然后通过该类的实例获得Connection对象,后续操作同JDBC相同。Dao层实现继承JdbcDaoSupport,内部获取getJdbcTemplate进行底层数据库操作。

②利用JdbcDaoSupport访问数据库的实现:

Dao的实现层继承JdbcDaoSupport,getJdbcTemplate获取模板对象,通过模板对象封装的方法操作数据库:

update:在模板中增删改统一用updae方法,几种重载形式:

update(sql,arg):其中arg是可变长度参数,用来为sql语句中占位符赋值。为了安全与复用,sql与hql均采用参数绑定机制。

queryForObject(slq,requiredClass,arg):用于查询一个字段,并且查询结果唯一。requeredClass表示查询字段的类型,以便对查询结果转型。

queryForList(slq,requiredClass,arg):用于查询一个字段,结果可能有多个。

queryForObject(sql,rowMapper,arg):查询结果是一个对象,其中rowMapper用于将查询字段封装成一个对象,查询结果必须包含对象的全部属性。

query(sql,rowMapper,arg):返回对个对象。

③数据源注入时自动创建模板,所以不需要在Dao的实现层显式注入JdbcTemplate的,即注入数据源时自动创建模板。

④系统自动在方法结束时销毁JdbcTemplate对象,因此每次在方法中使用时都需要重新创建。

⑤HibernateDaoSupport:支持在Hibernate中操作数据库的抽象类,开发者需要设置SessionFactory,然后获得Hibernate的实现,HibernatDaoSupport底层实现复杂,效率低,不建议使用。

4.JdbcDaoSupport/HibernateDaoSupport层级都高于对应的模板类,内部都提供了获取相应模板类的方法,与数库的交互通过模板类来完成。应用Spring提供的DAO模块时,自定义类通常继承XXXDaoSupport类,在自定义方法内部

获得响应模板类来具体操作数据库。

5.在实际开发中,先定义一个抽象DAO层,再创建一个实现层,抽象DAO层增删改查方法的名称与JDBC底层操作名称一致,服务层即具体利用DAO实现层进行数据库操作的层中,增删改查方法的名称与DAO层对应名称区分开。

 

五事务概述

1.Spring事务管理是基于AOP实现的,而Spring的AOP是以方法为单位的,所以Spring的事务属性就是对事务应用到方法上的策略。Spring的事务管理是利用AOP技术在DAO核心代码前后切入事务管理代码实现的。

2.Spring提供了PlatformTransactionManager接口来管理事务,该类提供了用于事务管理的通知,可以将该类视作切面,两个重要的实现类,不同的访问数据库的方式采用的实现类不同:

⑴DataSourceTransactionManager:适用于JDBC、Mybatis。

②HibernateTransactionManager:适用于Hibernate。

⑶事务管理器的核心操作是对事务的回滚与提交,而进行回滚或者提交时都需要建立与数据库的连接,因此需要把数据源传入事务管理器中。

3.Spring在默认情况下,发生运行时异常回滚,编译时异常提交。程序员可以改变回滚方式。

4.事务的四大属性分为传播行为、隔离级别、只读和超时。

⑴事务的传播行为用于确定是否将事务应用在方法上以及应用的策略,比如应用当前事务,新建事务。

5.Spring框架提供了两种对AOP思想的实现:一种是Spring自身的实现,另一种是兼容的AspectJ的实现,由于Spring的事务管理是基于AOP的,所以与AOP实现相对应,事务管理也有两种类型。

6.Spring事务管理的基本构成:代理工厂、目标对象、切点、切面、事务属性。

 

六基于Spring AOP的事务管理

1.在Spring AOP构成的四个要素:代理工厂、目标对象、切点、切面。

⑴代理工厂:在SpringAOP事务管理中采用TransactionProxyFactoryBean充当代理工厂。

⑵切面:在Spring事务管理中PlatformTransactionManager充当切面。

2.配置文件的编写:

<bean  id=""class="xxxTransactionProxyFactoryBean">//代理工厂
       <property  name="target" ref=""/>//目标对象
       <property  name="transactionManager"ref=""/>//切面
         //事务属性,就是事务应用到目标对象方法上的策略
       <property  name="transactionAttributes>
             <props>
                   <prop key="目标对象方法">事务四大属性</prop>
             </props>
      </property>
</bean>

3.为什么规定事务的属性?

因为目标对象中有多个方法,并不是所有方法都需要被事务管理,被事务管理的方法所需要的管理方式也不同,因此需要通过事务属性进行个性化定制,如ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-Exception。

4.Spring事务管理默认在发生编译时异常时提交,也可以设置成发生编译时异常回滚,在事务属性中设置:"-Excpetion",以负号开头,加异常,标识当发生该异常时事务回滚。

 

七基于AspectJ的事务管理

1.配置文件的编写:

<tx:advice  id="advice"tansaction-manager="transactionManger">
         <tx:attributes>
                 <tx:method  name="buyStock" isolation="DEFAULT"propagation="REQUIRED"rollback-for="StockProcessException" />
         </tx:attributes>
</tx:advice>
<aop:config>
         <aop:pointcut id="p01"expression="execution(xxxx)"/>
         <aop:advisoradvice-ref="advice"pointcut-ref="p01"/>
</aop:config>

 

八注解

1.以上两种事务管理是基于配置文件实现的,缺点是需要为每一个代理对象创建代理工厂,因此提供了基于注解的实现,可以方便地为多个对象创建代理:

⑴在配置文件中添加:<tx:annotation-driventransaction-manager="transactionManager"/>,指明事务管理器。

⑵在目标对象方法上添加以下注解,设定事务的属性:

@Transactional(isolation =Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor=StockProcessException.class)

Spring