
 
1.程序的耦合
       概述:也就是程序之间的依赖关系。调用者和被调用者的依赖关系。
       遇到“程序耦合”的情况:
(1)jdbc的注册驱动。
          DriverManager.registerDriver(new com.mysql.jdbc.Driver());
          我们在开发中遵循的原则:编译时不依赖,运行时依赖。
          解决依赖关系:使用反射创建类对象。
                   Class.forName(“com.mysql.jdbc.Driver”);
           使用反射创建类对象引发的新问题:类对象名固定了,换数据库时,需要修改源码。
                     解决的办法:使用配置文件,通过读取配置文件来反射创建类对象。
  (2)CRM客户联系人案例
              表现层,业务层相关联。都是一层一层new出来的。
              类路径:
                            普通工程:src下
                            Web工程: WEB-INF/classes
              解决的方法:使用工厂类来创建类对象。
              加载properties文件方法:
                     1、使用类加载器。(三步骤)
                            (1)Properties props=new Properties();
(2)InputStream in=类名.class.getClassLoader().getResourceAsStream(“文件名”);
       properties文件必须放在类路径下。
                     可以将文件放在src或者某个包下。
                                   InputStream in=new FileInputStream(“src/文件名”);
                            (3)props.load(in);
2、ResourceBundle类。
        这个类只能用于读取properties文件,别的文件读不了。
        这个类只能用于读取,不能写。
        这个类只能读取类路径下的文件,其它路径的读取不了。
        方法参数是按照包名.文件名(不带后缀)来写的。
        可以将文件放在src或者某个包下。
        ResourceBundle bundle=ResourceBundle.getBundle(“文件名,不带后缀”);
              代码实现:SpringReady项目
 
2.线程安全问题的分析
类成员变量有线程安全问题,方法成员变量没有。
       因为:方法独立进栈。
       有线程安全问题,有类成员变量,必须是多例的。例如:Action
       没有线程安全问题的前提下,单例对象更好。
       只有方法成员时,单例和多例对象都没有线程安全问题。
 
3.Spring概述
       分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(反转控制)和AOP(面向切面编程)为内核。
 
4.Spring的IOC
       概念:控制权发生改变,IOC即控制反转。
作用:用于解决程序间的耦合问题。即解耦
       IOC是一个重要的面向对象编程的法则来削减计算机程序的耦合问题,也是轻量级的spring框架的核心。控制反转一般分为两种类型:1、依赖注入(应用广泛)  2、依赖查找
 
5.Spring的体系结构
                            Spring的IOC(XML版)
6.搭建XML版的IOC开发环境
       (1)导入jar包
                     
  
       (2)在src创建bean.xml文件
                     导入schema约束:

7.Spring的入门案例
       ClassPathXmlApplicationContext  只能加载类路径下的配置文件
       FileSystemXmlApplicationContext  可以加载磁盘任意位置的配置文件
       1、获取容器
              ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);
       2、根据bean的id获取类对象
              类名 变量名=(类名)ac.getBean(“”);
       需求: 通过bean配置文件,创建相应的类对象。
       代码实现:Spring1项目   IOCXML.Demo01
 
8.Bean的两种创建规则
      
BeanFactory :
              提供的是一种延迟加载思想来创建bean对象。Bean对象什时候用什么时候创建。
              实现类:
                            XmlBeanFactory(Resource resource);
              步骤:
                     1、获取容器
                                   Resource resource=new ClassPathResource(“bean.xml”);
                                   BeanFactory factory=new XmlBeanFactory(resource); 
                     2、根据bean的id获取类对象
                                   类名 变量名=(类名)factory.getBean(“”);
       ApplicationContext :
提供的是一种立即加载思想来创建bean对象,只要解析完配置文件,就立马创建  bean对象。
              实现类:
                            ClassPathXmlApplicationContext  只能加载类路径下的配置文件
                            FileSystemXmlApplicationContext  可以加载磁盘任意位置的配置文件
              步骤:
                     1、获取容器
                                   ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);
                     2、根据bean的id获取类对象
                                   类名 变量名=(类名)ac.getBean(“”);
       代码实现:Spring1项目   Test.Demo02
 
9.Bean的三种创建方式
       Bean对象:也就是bean标签所对应的类对象。即class标签的值。
       第一种方式:调用默认无参构造函数创建(开发中用的最多)
              默认情况下,如果要创建的类中没有默认无参构造函数,则创建失败,会报异常。
              代码实现:Spring1项目      IOCXML.Demo03.test1()
 
第二种方式:使用静态工厂中的方法创建对象
       写法:
              
              代码实现:Spring1项目   Factory.StaticFactory   IOCXML.Demo03.test2()
       第三种方式:使用实例工厂中的方法创建
       写法:
              
              
              代码实现:Spring1项目   Factory.InstanceFactory   IOCXML.Demo03.test3()
10.Bean的作用范围
       单例对象作用范围:整个应用
       多例对象作用范围:一次使用的过程中
Bean对象可以通过配置的方式来调整作用范围。
配置的属性:bean标签的scope属性
属性的取值:
       singleton   单例的(默认值)
prototype  多例的(当我们让spring接管struts2的action创建时,action必须配
                 置此值) 
              request    作用范围是一次请求和当前请求的转发。
              session     作用范围是一次会话
              globalsession   作用范围是一次全局会话。(服务器集群)
代码实现:Spring1项目   IOCXML.Demo04
 
11.Bean的生命周期
       涉及的两个属性:
              init-method
              destroy-method
                     因为main出栈后,该线程还没有调用此配置的方法,栈内已经无元素。
       单例:
              出生:容器创建,对象就出生了
              活着:只要容器在,对象就一直存在
              死亡:容器销毁,对象消亡
       多例:         
              出生:每次使用时,创建对象
              活着:只要对象在使用中,就一直活着
              死亡:当对象长时间不使用,并且也没有别的对象引用时,java的垃圾回收器回收
 
12.Spring的依赖注入
       注入的方式有三种:
              第一种:使用构造函数注入
              第二种:使用set方法注入
              第三种:使用注解注入
       注入的数据类型有3类:
              第一类:基本类型和String类型
              第二类:其他bean类型(必须在Spring配置文件中出现过的bean)
              第三类:复杂类型(集合类型)
 
13.Spring的依赖注入—构造函数注入
       涉及的标签:
              constructor-arg
       标签的属性:
              type: 指定参数的类型
              index: 指定参数的索引位置
              name: 指定参数的名称   (一般用它)
              ====上面三个属性是指定给哪个参数赋值的,下面两个属性是指定赋什么值==
              value: 指定基本数据类型或String类型的数据  (直接赋值即可)
              ref: 指定其他bean类型数据
       标签出现的位置:
              写在bean标签内部
       案例:使用构造函数注入,注入基本类型和String类型      
       代码实现:Spring1项目   IOCXML.Demo06
 
14.Spring的依赖注入—set方法注入
       涉及的标签:
              Property
              当对复杂数据类型进行注入时,需要使用子标签。
              结构相同,可以使用结构相同的标签。
              子标签:
                     array
                            
       
list
       
       
                     map
       
set
                            
       
                     props
                            
       
       标签的属性:
              name: 指定参数的set方法名称   (一般用它)
              value: 指定基本数据类型或String类型的数据(直接赋值即可)
              ref: 指定其他bean类型数据
       标签出现的位置:
              写在bean标签内部
       案例1:使用set方法注入基本数据类型和String数据类型 
       代码实现:Spring1项目   IOCXML.Demo07
      
案例2:使用set方法注入复杂数据类型(集合类型)
代码实现:Spring1项目   IOCXML.Demo08
 
15.SpringProject1项目
       目的:对每个变量进行XML-IOC的依赖注入
代码实现:SpringProject1项目
 
                     Spring的IOC(注解版)
16.搭建注解版的IOC开发环境
    (1)导包
            
    (2)在src下创建bean.xml
   
17.注解的分类
    (1)用于创建bean对象
    (2)用于注入数据的
(3)用于改变作用范围的
(4)和生命周期相关的  (了解)
(5)spring的新注解
      
18.创建bean对象的注解配置
       (1)@Component
              作用:就相当于一个bean标签。
要求:要调用此类的方法,才让此类进入容器,成为bean对象,由Spring创建。
              能出现的位置:类上面
              属性:value。
含义是指定bean的id。当不写时,它有默认值,默认值是当前类的类名,    并且首字母小写。
              由此衍生的三个注解:
                     @Controller   一般用于表现层
                     @Service        一般用于业务层
                     @Repository   一般用于持久层
                     它们和@Component的作用及属性都是一模一样的。
       (2)< context:component-scan >标签
              目的:告知spring在创建容器的时要扫描的包。当配置了此标签后,spring创建容
                       器就会去指定的包以及子包下找对应的注解。
              前提:导入context约束
              属性:base-package
                     告诉spring去哪个包寻找注解
       代码实现:Spring2项目   
 
19.注入数据的注解配置
       当我们使用注解配置时,set方法不是必须的。
       1、复杂数据类型(集合)不能通过注解注入实现。
2、注入其它Bean类型数据:
              (1)@Autowired
                            作用:自动按照类型注入。只要有唯一的类型匹配就能注入成功。
                            注意:  
当类型不是唯一时,会报异常。
当类型不是唯一时,spring会把变量名作为bean的id,在容器中查找。
              (2)@Qualifier
                            作用:在自动按照类型注入的基础上,再按照bean的id注入
                            属性:value,用于指定Bean的id。
                            注意:
在给类成员注入数据时,不能独立使用。
                                   在给方法的形参注入数据时,可以独立使用。
                                          在方法形参的最前面使用:
                                                 例如:(@Qualifier(“Bean的name值”)DataSource dataSource)
              (3)@Resource
                            作用:根据bean的id注入数据
                            属性:name,用于指定Bean对象的id
       3、注入基本数据类型和String类型
              (1)@Value
                            作用:用于注入基本类型和String类型数据。
它可以借助spring的el表达式读取properties文件中的配置。
                            属性:value。用于指定要注入的数据。可不写value这几个字母。
 
20.Bean作用范围的注解配置
       @Scope
              作用:用于改变Bean的作用范围。
              属性:value。用于指定范围的取值
                            取值和xml中scope属性的取值是一样的。
                     value的取值:
                       singleton     单例的(默认值)
prototype    多例的(当我们让spring接管struts2的action创建时,action必须配置此值)  
                             request       作用范围是一次请求和当前请求的转发。
                              session        作用范围是一次会话
                              globalsession   作用范围是一次全局会话。(服务器集群)
       代码测试:Spring2项目   Service.CustomerService   Test.Demo01
21.Bean生命周期的注解配置
       @PostConstruct
              作用:用于指定初始化方法。
       @PreDestroy
              作用:用于指定销毁方法
      
22.Spring的新注解(为了将xml文件完全删除而引出的注解)
(1)@ComponentScan
                 作用:告诉spring去哪个包寻找注解。相当于  
                 属性:value。可不写。数组类型。指定哪个包。
使用:@ComponentScan({“  ”, ”  ”})
                 使用的位置:类上
(2)@Bean
                     作用:把方法里的返回值存入spring容器。
                     属性:name。用于指定bean的id。不写时有默认值,默认值是方法名称
                     使用的位置:方法上
       (3)@Configuration(没有多大的用处)
                     作用:把当前类看成是Spring的配置类
                     使用:
                            将bean.xml放在和配置类同一个包下。
                            读取容器:new ClassPathXmlApplicationContext(“bean.xml”,配置类名.class);
                     使用的位置:类上
       (4)@Import
                     作用:导入其他配置类。
                     属性:value。数组类型。可不写value。指定其它配置类。
                     使用的位置:配置类上
                     使用:@import({类名.class})
       (5)@PropertySource
                     作用:用于指定properties文件
                     属性:value。指定文件的路径。
                     使用的位置:配置类上
                     使用:
                            @PropertySource({“classpath:XX/XXX.properties”})
                            配合Spring的el表达式。需要解析器解析el表达式。
                                   @Value=(“${key}”)  会自动解析property内的key对应的值
       代码实现:SpringProject2项目   Config.SpringConfiguration
 
23.Spring的EL表达式 
       Spring 4.3之后的版本自带解析器,来解析EL表达式。
       Spring 4.3之前的版本没有自带解析器,需要自己配置。                   
       语法: ${}
       自己配置:
              在配置类中添加方法。
              @Bean
public static PropertySourcesPlaceholderConfigurer create(){
       return new PropertySourcesPlaceholderConfigurer();
}
                    
24.java代码创建容器—-注解版
       原因:这时没有bean.xml文件存在,所以不能使用
new  ClassPathXmlApplicationContext(“bean.xml”);
       步骤:
              1、获取容器
                            ApplicationContext ac
=new AnnotationConfigApplicaionContext(SpringConfiguration.class);
              2、根据bean的id获取类对象
                            类名 变量名=(类名)ac.getBean(“”);
       代码实现:SpringProject2项目   Test.CustomerServiceTest
 
25.关于xml和注解的选择问题
       Xml:
              优点:不需要修改源码
              缺点:有的地方会繁琐。如果文件过多时,维护困难。
       注解:
              优点:清晰明了。
              缺点:需要修改源码部分。
       选择的原则:
              反复要修改配置,选择Xml。
              不需要经常修改,选择注解。
 
26.Spring整合junit单元测试
       步骤:
              1、导包:spring-test-4.2.4.RELEASE.jar
              2、使用junit提供的一个注解,把原来的main函数替换掉,换成spring提供的
                            @RunWith(SpringJunit4ClassRunner.class)
                            要换的类:SpringJunit4ClassRunner
3、使用Spring提供的注解告知Spring,配置文件或注解类所在的位置
              @ContextConfiguration              
如果是配置文件,使用locations
                            @ContextConfiguration(locations={“classpath:bean.xml”}
                     如果注解类,使用classes
                            @ContextConfiguration(classes={XX.class})
       原理:
              源码:注解存在源码阶段。
编译后:一旦变成字节码class文件,还存在
运行时:进入虚拟机,会出现注解擦除。
       代码测试:SpringProject2项目    Test.CustomerServiceTest 
 
27. SpringProject2项目(纯注解版)
目的:对每个变量进行IOC的注解配置
代码实现:SpringProject2项目
 
                                   动态代理
28.动态代理
    作用:不改变源码的基础上,对已有方法的增强。(它是AOP思想的实现技术)
    分类:
       1、基于接口的动态代理
2、基于子类的动态代理
    代理对象:可以理解为“管理对象的类”
 
29.基于接口的动态代理
    代码测试:Spring3项目    proxy包
要求:被代理类至少实现一个接口
    提供者:JDK官方
    涉及的类:Proxy
    创建代理对象的方法:newProxyInstance(ClassLoader,class[],InvocationHandler)
参数的含义:
ClassLoader:类加载器,和被代理对象使用相同的类加载器。
       一般都是固定写法。
被代理类的对象.getClass().getClassLoader()
    Class[]:字节码数组。被代理类实现的接口。
          (要求代理对象和被代理对象具有相同的行为,行为即方法。
也就是实现相同的接口,因而具有相同的方法。)
           一般都是固定写法。
被代理类的对象.getClass().getClassLoader().getInterfaces()
    InvocationHandler :它是一个接口。就是用于我们提供增强代码的。
                      我们一般都是写一个该接口的实现类。实现类                            可以是匿名内部类。它的含义:如何代理。
此处的代码只能是谁用谁提供。
                     策略模式:
                            使用要求:数据已经有了。
目的明确。
达成目标的过程就是策略
                     在dbUtils中的ResultSetHandler就是策略模式的具体应用。
            匿名内部类重写的方法invoke:
                  执行被代理对象的任何方法都会经过该方法,该方法有拦截的功能。
                  方法的参数:
                     Object proxy:代理对象的引用
                     Method method:当前执行的方法
                     Object[] args:当前执行方法的参数
                  返回值:
                     当前执行方法的返回值
 
30.基于子类的动态代理
    代码测试:Spring3项目   cglib包
    要求:被代理类不是最终类,不能被final修饰
    提供者:第三方CGLIB
    涉及的类:Enhancer
    创建代理对象的方法:create(Class,Callback);
    参数的含义:
       Class:被代理对象的字节码
       Callback:如何代理。它和InvocationHandler的作用是一样的。它也是一个接口。
               我们一般使用该接口的子接口,即MethodInterceptor。
               在使用时我们也是创建该接口的匿名内部类。
           匿名内部类重写的方法intercept:
              执行被代理对象的任何方法,都会经过该方法。
              方法的参数:
                  Object proxy:代理对象的引用
                  Method method:当前执行的方法
                  Object[] args:当前执行方法所需的参数
                  MethodProxy methodProxy: 当前执行方法的代理对象。一般不用
 
31.动态代理的具体应用
    (1)连接池原理
           连接池的close方法不是直接关闭,而是归还给连接池。
           这里便使用了动态代理的思想。
    (2)实现业务层的事务控制
           业务层(Service)不再对事务进行管理。交于代理对象进行管理。
           从而实现业务层一个方法内只有一句的代码。
       代码实现:Struts2Project1项目   Factory.BeanFactory  
Utils.TransactionManager    Service.CustomerService
 
32.什么是AOP
    全称:Aspect Oriented Programming  即:面向切面编程。
    把重复代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础
    上,对我们的已有方法进行增强。
 
33.AOP的作用及优势
    作用:在程序运行期间,不修改源码对已有方法进行增强。
    优势:减少重复代码   提高开发效率   维护方便
 
34.AOP的实现方式
    使用动态代理的技术。
 
               AOP(XML版)
35.基于XML文件的AOP配置步骤
    第一步:导入jar包
       
    第二步:把通知类交给spring来管理
       通知类:增强的代码
       
第三步:导入AOP名称空间,并且使用aop:config开始AOP的配置               
第四步:使用aop:aspect配置切面
       切面:增强的代码和需要增强的方法的结合
       使用:在aop:config内部使用。属于aop:config的子标签。
           
              
属性:
id:用于给切面提供唯一标识。
           ref:用于引用通知类bean的id
 
    第五步:配置通知的类型,指定增强的代码何时执行(在
       方法执行之前,执行增强的代码:
属性:
    method:用于指定增强的方法名称
           pointcut:用于指定需要增强的方法。切入点表达式
             
36.切入点表达式
关键字:execution(表达式)
       表达式的写法:
1、全匹配方式
访问修饰符 返回值 包名.类名.方法名(参数列表)   
(1)访问修饰符可省略
(2)返回值可以使用通配符,表示任意返回值。
(3)包名可以使用通配符,表示任意包。但是有几个包需要写几个。
      例如:三个包:...
(4)包名可以使用..表示当前包及其子包
(5)类名和方法名都可以使用通配符
(6)参数列表可以使用具体类型,来表示参数类型
基本类型直接写类型名称
引用类型必须是包名.类名
(7)参数列表可以使用通配符,表示任意类型。必须有参数
(8)参数列表可以使用.. 表示有无参数均可。参数可以是任意类型
2、全通配方式: ...(..)
      
实际开发中,我们一般情况下,都是对业务层方法进行增强:
       所以写法: Service..(..)
 
37.配置通用的切入点表达式
    如果写在了aop:aspect标签内部,则表示只有当前切面可用。
    如果写在了aop:aspect标签外部,则表示所有切面可用。必须写在aop:aspect之前
定义:
标签:aop:pointcut
           属性:
               expression:切入点表达式
               id:指定该通用切入点表达式的唯一标识
    使用:
       标签:aop:before ,aop:after等
           属性:
       method:用于指定增强的方法名称
              pointcut-ref:用于指定通用的切入点表达式id
 
38.四种通知类型
    前置通知:aop:before
       永远在切入点方法之前执行
    后置通知:aop:after-returning
       切入点方法正常执行之后执行
    异常通知:aop:after-throwing
       切入点方法产生异常之后执行,它和后置通知永远只有一个
最终通知:aop:after
    无论切入点方法是否正常执行,它都会在其后面执行
环绕通知:aop:around
问题:当我们配置了环绕通知,切入点方法没有执行,而环绕通知的代码执行了。
    分析:由动态代理可知,环绕通知指的是invoke方法。并且里面有明确的切入点
         方法调用,而我们现在的环绕通知没有明确的切入点方法调用。
    解决:
       Spring为我们提供了一个接口:ProceedingJoinPoint。该接口可以作为环绕
       通知的方法参数来使用。在程序运行时,spring框架会为我们提供该接口的
       实现类。
       该接口中一个方法:proceed()。必须try,catch捕获异常。作用等同于
method.invoke()。就是明确调用业务层的核心方法(切入点方法)
try{
  前置代码1;
  proceed();
  后置代码2;
}catch(Throwable e){
  异常代码3;
}finally{
  最终代码4;
}
代码测试:Spring3项目   Utils.Logger  AOPXML.Client
 
39.切入点表达式的执行顺序
       同种通知表达式,配置在前的先执行。
 
           AOP(纯注解版)
40.配置AOP注解版幻境
    1、导入jar包
       
  
    2、导入约束
40.配置切面
    在增强代码的类上方,配置该类为切面。
    标签:@Aspect  @Component(“”)
    使用位置:类上方
    代码测试:Spring4项目    Utils.Logger
 
41.切入点表达式
    定义:
        @Pointcut(“execution( Service..(..))”)
        private void pt1(){}
    引用:
       @Before(“pt1()”)
    代码测试:Spring4项目    Utils.Logger
 
42.四种通知类型(在方法的上方配置)
    前置通知:@Before
       永远在切入点方法之前执行
    后置通知:@AfterReturning
       切入点方法正常执行之后执行
    异常通知:@AfterThrowing
       切入点方法产生异常之后执行,它和后置通知永远只有一个
最终通知:@After
    无论切入点方法是否正常执行,它都会在其后面执行
环绕通知(建议使用):@Around 
代码测试:Spring4项目    Utils.Logger
   
43.开启Spring对注解AOP的支持
    在bean.xml文件中:
    在配置类上方:@EnableAspectJAutoProxy
    代码测试:Spring4项目    bean.xml   Config.SpringConfiguration
 
              JdbcTemplate
44.概述
    它是Spring框架提供的一个对象,是对原始Jdbc API对象的简单封装。Spring框架
    为我们提供了很多的操作模板类。
 
45.JdbcTemplate的基本用法(不使用配置文件bean.xml)
     代码实现:Spring5项目   JdbcTemplate.Demo01
    (1)导包
           
(2)创建连接对象
           DriverManagerDataSource ds=new DriverManagerDataSource();
    (3)设置四大参数
           ds.setDriverClassName(“com.mysql.jdbc.Driver”);
           ds.setUrl(“jdbc:mysql://localhost:3306/mydb6”);
           ds.setUserName(“root”);
           ds.setPassword(“29811055”);
    (4)获取JdbcTemplate
           JdbcTemplate jt=new JdbcTemplate();
    (5)将JdbcTemplate与DataSource关联
           第一个方法:jt.setDataSource(ds);
           第二个方法:JdbcTemplate jt=new JdbcTemplate(ds);
46.JdbcTemplate的基本用法(使用配置文件bean.xml)
     代码实现:Spring5项目   JdbcTemplate.Demo02  bean.xml
    (1)导包  
        
(2)配置Bean对象
(3)获取JdbcTemplate
    ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);    JdbcTemplate jt=(JdbcTemplate)ac.getBean(“bean的id”);
 
47.JdbcTemplate的CRUD操作(增,删,改,查)
    (1)增(插入数据)
          方法:
execute(String sql);
    参数:
       sql:不带参数的sql语句
               update(String sql,Object…params);
                 参数:
                     sql:带参数的sql语句
                     params: sql语句中的参数值,按顺序赋值
       代码实现:Spring5项目   JdbcTemplate.Demo03
(2)删(删除数据)
       方法:
execute(String sql);
    参数:
       sql:不带参数的sql语句
               update(String sql,Object…params);
                 参数:
                     sql:带参数的sql语句
                 params: sql语句中的参数值,按顺序赋值 
       代码实现:Spring5项目   JdbcTemplate.Demo04
(3)改(更新数据)
       方法:
execute(String sql);
    参数:
       sql:不带参数的sql语句
               update(String sql,Object…params);
                 参数:
                     sql:带参数的sql语句
                 params: sql语句中的参数值,按顺序赋值
       代码实现:Spring5项目   JdbcTemplate.Demo05
(4)查(查询数据)
       代码实现:Spring5项目   JdbcTemplate.Demo06
        1、查询所有或多个
           方法:
               query(String sql,RowMapper
               query(String sql, RowMapper
                  参数:
                      sql:不带参数的sql语句
                      rowMapper:查询结果的结果集
                         实现类:
                              BeanPropertyRowMapper
                         使用:
new BeanPropertyRowMapper<类名>(类名.class)
                                 params:sql语句的参数值,按顺序赋值
        返回值:
             List
        2、查询一个
           同上。
       3、查询返回一行一列:聚合函数的使用
           方法:
              queryForObject(String sql,T.Class
(Spring 3.x之后的新方法。)
                  返回值:T
                  参数:
                     sql:带参数的sql语句
                     type:返回值类型.class
                     params:sql语句中的参数值,按顺序赋值
              queryForInt  queryForLong 。。 (Spring 2.x时的方法)
 
48.JdbcTemplate在dao层中的使用方式1
    (1)在dao层创建JdbcTemplate类型的成员变量
(2)set方法或者构造函数注入
    (2)在bean.xml配置(不适合使用注解配置)
    代码实现:Spring5项目   JdbcTemplate.Demo07  Dao.CustomerDao
 
49.JdbcTemplate在dao层中的使用方式2
(1)dao继承JdbcDaoSupport
       获取JdbcTemplate :getJdbcTemplate();
 
(2)配置dao层。不需要配置JdbcTemplate。
       
           
    代码实现:Spring5项目   JdbcTemplate.Demo08  Dao.CustomerDao2
 
50.JdbcTemplate使用其它数据库连接池
    在bean.xml中配置JdbcTemplate,并配置DataSource。
    
       
    代码实现:Spring5项目  bean.xml
 
51.使用Spring配置修改Struts2Project1项目
    代码实现:SpringProject3项目(纯xml版本)
 
52.使用Spring配置修改Struts2Project1项目
    代码实现:SpringProject4项目(xml和注解版本)
 
53.使用Spring配置修改Struts2Project1项目
    代码实现:SpringProject5项目(纯注解版本)
 
           Spring事务控制
54.概述
    (1)事务处理位于业务层(Service层)
    (2)Spring框架提供了一组事务控制的接口。在spring-tx-4.2.jar包中
    (3)Spring的事务控制都是基于AOP的,可以使用编程实现,也可以使用配置
        实现。(重点:配置方式)
 
55.Spring事务控制的API介绍
(1)PlatformTransactionManager
    此接口是Spring的事务管理器。
    方法:
1、 获取事务状态信息
TransactionStatus  getTransaction(TransactionDefinition definition)
2、 提交事务
void commit(TransactionStatus status)
3、 回滚事务
void rollback(TransactionStatus status)
       实现类:
           DataSourceTransactionManager 
使用SpringJDBC或iBatis进行持久化数据时使用
           HibernateTransactionManager
              使用Hibernate5.0版本进行持久化数据时使用
(2)TransactionDefinition
    事务的定义信息对象。
    方法:
       1、获取事务名称
           String getName()
2、获取事务隔离级别
    int getIsolationLevel()
    事务的隔离级别:
                  事务隔离级别反映事务提交并发访问时的处理态度。
(1)SERIALIZABLE串行化(可以解决三种读问题):
1.  不会出现任何并发问题。因为它对同一数据的访问是串行的。
2.  性能最差。
(2)REPEATABLE READ可重复读(MySql默认):
           1.防止脏读和不可重复读
2. 性能比SERIALIZABLE好
(3)READ COMMITTED读已提交数据(Oracle默认):
1.  只能处理脏读
2.  性能比REPEATABLE READ好
(4)READ UNCOMMITTED(读未提交数据):
1.  可能出现任何事物并发问题
2.  性能最好
 
       3、获取事务传播行为
           int getPropagationBehavior()
           事务的传播行为:
              (1)REQUIRED:如果当前没有事务,就创建一个事务。如果已经存在一个
事务中,加入到这个事务中。一般的选择(默认值)增,删,改方法。
(2)SUPPORTS:支持当前事务。如果当前没有事务,就以非事务方式执行。
查询方法
   
       4、获取事务超时时间
           int getTimeout()
           事务的超时时间:
              默认值是-1,没有超时限制。如果有,以秒为单位进行设置。
 
       5、获取事务是否只读
           boolean isReadOnly()
           读写型事务:增加、删除、修改开启事务
           只读性事务:执行查询时,包含开启事务(查询时设置为只读)
    (3)TransactionStatus
       描述了某个时间点上事务对象的状态信息。
      
方法:
    1、刷新事务
       void flush()
    2、获取是否存在存储点
       boolean hasSavepoint()
    3、获取事务是否完成
       boolean isCompleted()
    4、获取事务是否为新的事务
       boolean isNewTransaction()
    5、获取事务是否回滚
       boolean isRollbackOnly()
    6、设置事务回滚
       void setRollbackOnly()
 
56.Spring的事务控制—-搭建环境(使用xml配置)
(1)导入jar包
        
(2)bean.xml文件导入约束
 
57.案例1:模拟转账。
代码实现:Spring6项目  
(3)创建Domain包
在Domain包下创建实体类。与数据库相对应。
(4)创建Dao层和Service层
            Dao层下创建AccountDao类,继承JdbcDaoSupport类。
            配置AccountDao。
           配置AccountService。
    (5)在Test.Client测试类中 测试Service层(业务层)的转账方法transfer()
结论:有异常的情况下,转账必须失败。但是这里还没有配事务,会出现问题。
 
58.Spring基于XML的声明式事务的配置(纯XML版)
    代码实现:Spring7项目
    (1)搭建事务配置的环境
           略
    (2)创建Domain,Dao,Service包和Acount,AcountDao,AcountService类。
        此处AccountDao继承JdbcDaoSupport。不需要有JdbcTemplate类型的成员变量
    (3)进行Spring的IOC配置(使用XML配置)
           第一步:配置Service层。(略)
           第二步:配置Dao层。
                  
       第三步:配置Spring内置的DataSource(略)
(4)基于XML的声明式事务控制
       第一步:配置事务管理器。
    
    第二步:配置事务的通知。(对应AOP的通知类)
        不需要配置切面AOP,Spring会自动提交和回滚事务。
    
    
    第三步:配置aop
        
           <!—切入点表达式 —>
               
 
<!—配置事务通知和切入点表达式的关联 —>
           第四步:配置事务的属性。在tx:advice标签内配置。
              用法:
                     
        标签:
作用:用于指定某个方法内,事务的属性。
       
属性:
           name:指定哪个方法。优先级:<find
isolation:配置事务的隔离级别。默认值:DEFAULT,使用数据库的默
         认隔离级别。Mysql是REPEATABLE_READ
propagation:配置事务的传播行为。默认值:REQUIRED。一般的选择。
           (增删改方法)。查询方法时,选择SUPPORTS
timeout:指定事务的超时时间。默认值:-1,永不超时。当指定其它
       值时,以秒为单位。
read-only:配置是否是只读事务。默认值:false,读写型事务。当
         指定为true时,表示只读,只能用于查询方法。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。
            产生其它异常时,事务不回滚。没有默认值,任何异
            常都回滚。
no-rollback-for:用于指定一个异常,当执行产生该异常时,事务不
回滚。产生其它异常时,事务回滚。没有默认值,任何异常都回滚。
      
59.Spring基于XML和注解组合的声明式事务的配置(XML和注解组合)
     代码实现:Spring8项目
    (1)搭建事务配置的环境(略)
    (2)创建Domain,Dao,Service包和Acount,AcountDao,AcountService类。
        此处AccountDao要有JdbcTemplate类型的成员变量 直接@Autowired 
(3)进行Spring的IOC配置(使用注解配置)
           第一步:配置Service层。(略)
           第二步:配置Dao层。(略)
                  在bean.xml中需要配置jdbcTemplate。
           第三步:配置Spring内置的DataSource(略)
    (4)基于XML和注解组合的配置步骤
           第一步:配置事务管理器(XML)
    
           第二步:配置Spring开启注解事务的支持(XML)
              
           第三步:在需要事务的地方使用@Transactional注解(一般都是Service层)
              @Transactional的使用位置:接口上,类上,方法上。
                      写在接口上,表示该接口的所有实现类都有事务。
                      写在类上,表示该类的所有方法都有事务。
                      写在方法上,表示该方法有事务。
              优先级:方法上>类上>接口上
              属性:
isolation:配置事务的隔离级别。默认值:DEFAULT,使用数据库的默
         认隔离级别。Mysql是REPEATABLE_READ
propagation:配置事务的传播行为。默认值:REQUIRED。一般的选择。
           (增删改方法)。查询方法时,最好选择SUPPORTS
timeout:指定事务的超时时间。默认值:-1,永不超时。当指定其它
       值时,以秒为单位。
read-only:配置是否是只读事务。默认值:false,读写型事务。当
         指定为true时,表示只读,只能用于查询方法。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。
            产生其它异常时,事务不回滚。没有默认值,任何异
            常都回滚。
no-rollback-for:用于指定一个异常,当执行产生该异常时,事务不
回滚。产生其它异常时,事务回滚。没有默认值,任何异常都回滚。
          
60.Spring基于注解的声明式事务的配置(纯注解配置)
    代码实现:Spring9项目
    (1)搭建事务配置的环境(略)
    (2)创建Domain,Dao,Service包和Acount,AcountDao,AcountService类。
        此处AccountDao要有JdbcTemplate类型的成员变量  直接@Autowired
    (3)进行Spring的IOC配置(使用注解配置)
           第一步:配置Service层。(略)
           第二步:配置Dao层。(略)
                  在bean.xml中需要配置jdbcTemplate。
           第三步:配置Spring内置的DataSource(略)
    (4)基于注解的配置步骤
           第一步:创建Config包,在包下创建SpringConfiguration核心配置类。
              在类上配置要扫描的包和导入其他配置类。
                  要扫描的包:@ConponentScan({“Service”,”Dao”})
                  导入其它配置类:Import({JdbcConfig.class,
TransactionManager.class})
                  开启Spring对注解事务的支持:@EnableTransactionManagement
           第二步:在Config包下创建连接数据库的配置类。class JdbcConfig
              在类的内部写带有返回值的二个方法:
                  @Bean(name=”jdbcTemplate”)
                  public JdbcTemplate 方法名(DataSource dataSource)
                  {
                     Return new JdbcTemplate(dataSource);
}
@Bean(name=”dataSource”)
                  public DataSource 方法名(DataSource dataSource)
                  {
                     DriverManagerSource ds=new DriverManagerDataSource();                        //用set方法设置连接数据库的四大参数
                     (略) 
                     return ds;
}
           第三步:在Config包下创建事务管理器的配置类。class TransactionManager             在类的内部写带有返回值的方法:
@Bean(name=”transactionManager”)
public PlatformTransactionManager getTransactionManager
(DataSource dataSource)
{
                  return new DataSourceTransactionManager(dataSource);
}
           第四步:在需要事务的地方使用@Transactional注解(一般都是Service层)
 
                 
                  SSH整合
61.整合三个版本
    第一个版本:纯XML的整合。保留spring,struts2,hibernate各自的主配置文件。
    第二个版本:纯XML的整合。保留spring和struts2的主配置文件,hibernate的
              主配置文件内容配到spring的配置文件中。
    第三个版本:XML和注解的组合式整合。仅保留spring的主配置文件(根据实际开发
的需要,struts2的配置文件也可以保留。)
    版本选择: 
           第一个版本和第二个版本任意选择一个。
           第三个版本就一定要会。
 
62.整合步骤
    第一步:保证spring的ioc容器能够在web工程中独立运行。
    第二步:保证hibernate框架能够在web工程中独立运行。
    第三步:整合spring和hibernate
       1、Spring接管了hibernate的sessionFactory对象创建(把seesionFactory存
          入Spring容器中)
2、使用了spring的声明式事务控制
    第四步:保证struts2框架能够在web工程中独立运行
    第五步:整合spring和struts2
       1、action的创建交给spring来管理
       2、保证web工程的容器只有一个
    第六步:优化已有的整合配置
       1、配置文件的位置存放可以调整
       2、配置文件的内容可以分不同文件来编写
 
63.第一个版本的整合   代码实现:SSH01项目  
    整合步骤的第一步:
        1、编写Domain包下的客户实体类
        2、编写Service和Dao层(还没有实现功能)
        3、导入Spring的IOC,AOP,事务控制的相关jar包
        4、在src下创建bean.xml并导入AOP和IOC有关的约束     
        配置Service层和Dao层
5、测试spring的ioc容器是否能够在web工程中独立运行?
代码测试:Tes.Test01Spring
 
    整合步骤的第二步:
       1、搭建hibernate的开发环境,导入jar包
       2、在Domain包下创建映射配置文件(实体类类名.hbm.xml)
          导入约束:
约束的路径:hibernate-core/org.hibernate/hibernate-mapping-3.0.dtd
           配置实体类映射。(略)
3、在src下创建主配置文件(hibernate.cfg.xml)
              编写主配置文件(略)
       4、测试hibernate框架是否能够在web工程中独立运行?
              代码测试:Test.Test02Hibernate
 
    整合步骤的第三步:
       1、实现Dao层的功能。
           在CustomerDao类:
创建HibernateTemplate类型的成员变量,并带set方法。
       原因:该类型是spring提供的,是对hibernate的session对象进
                       行了简单的封装。包为:hibernate5.HibernateTemplate
                  方法:
                     保存:hibernateTemplate.save(Object obj);
                     查询:hibernateTemplate.find(HQL语句);
                            返回值:List
2、在baen.xml中配置HibernateTemplate
       3、在bean.xml配置SessionFactory。即由Spring接管SessionFactory的创建。
           (1)用Spring提供的SessionFactory:LocalSessionFactoryBean
              
           (2)常见SessionFactory有三部分必不可少的信息。信息都在hibernate主
配置文件中。所以把Hibernate的主配置文件注入进去。
       
4、在bean.xml配置spring的声明式事务控制
     (1)配置事务管理器。此处使用HiberbateTransactionManager
       
           (2)配置事务的通知(略)
           (3)配置事务的aop (略)
       5、使用Spring的配置把session和线程绑定
           原因:Spring不支持Hibernate中session和线程绑定的配置
           解决的办法:将Hibernate原先的配置删去。Spring的HibernateTemplate                       默认将session和线程绑定了。无需配置。
    整合步骤的第四步:
       1、搭建struts2的开发环境并测试(略)
       2、编写Action动作和配置(略)
       3、配置Spring提供的监听器。(Servlet自带8大监听器)
           原因:动作类是多例的,每次都会创建新的容器,导致容器的bean也会
                创建新的。
           目的:应用加载时,创建CustomerService。应用结束时,销毁CustomerService           应用加载,ServletContext创建。
           配置:
              1、导入jar包。
spring-web.jar
              2、在web.xml内配置spring提供的监听器。用于监听ServletContext               对象的创建,同时为我们创建spring的容器。
                  
                     
org.springframework.web.context.ContextLoaderListener
                     
              3、创建Spring的容器后,为了下次可以再用,Spring替我们将容器
存在了应用域中。
获取ServletContext:
       ServletContext application=
ServletActionContext.getServletContext();
                     获取Spring容器:
                         ApplicationContext ac=WebApplicationContextUtils.
                         getWebApplicationContext(application);
                     获取bean对象:
                         ac.getBean(“customerService”)   
              4、ServletContextListener监听器
                             
                  默认情况下:只能加载位置是在WEB-INF目录中的Spring配置文件,
                             同时文件名称必须是applicationContext.xml
                  所以修改bean.xml文件的位置和名称。
   
    整合步骤的第五步:
       1、导入jar包
              struts2-spring-plugin-2.3.24.jar
       2、Action类必须要有Service的set方法。
           (1)原来创建action的类是struts2提供的。
           (2)导入jar包后,类改变了,它会自动加载容器和调用set方法。
                  原因:jar包内有一个配置文件,会覆盖struts-default的配置。
           (3)Action类的构造函数不需要写以下的任何方法。    
 
64.第二个版本的整合   代码实现:SSH02项目
    说明:其余的配置不再重复。此项目是基于SSH01的基础上作修改的。 
1、将Hibernate主配置文件中的内容都交给Spring来管理。删除Hibernate主配置文件也就是在applicationContext.xml中配置Hibernate主配置文件中的内容。
       (1)首先将bean.xml中配置了hibernate主配置文件的位置的语句删了。
           删掉:
       (2)配置第一部分:数据库的连接池
              
            接着配置dataSource。(略)
       (3)配置第二部分:hibernate的可选配置。因为都是键值对类型。
            使用
       (4)配置第三部分:映射文件的位置
             写法:
               
                  
    
              name属性取值:
mappingResources:它是一个注入String数组类型的数据。提供的是
                              映射文件的位置。有几个映射文件,就需要写几个。
                mappingDirectoryLocations:它是注入一个Resource类型的数据。提供
的是映射文件的目录。此属性一般多用于一个项目有多个地方存放映射配置。
                      //服务端
                         Server_domain
                      //移动端
                         Mobile_domain
                mappingLocations:它是注入一个Resource类型的数据。提供的是映射
                              文件的位置。它可以使用通配符。
           配置:
              
2、优化:手动指定Spring配置文件applicationContext.xml的位置
       原因:Spring提供的ServletContext监听器会自动加载配置文件。
       解决的办法:设置ServletContext的初始化参数。来指定配置文件的位置。       配置:在web.xml文件内进行配置。
         
            
             
          
    3、优化:手动指定Stuts2配置文件struts.xml的位置
       原因:struts2的核心过滤器会自动加载struts2的配置文件
       解决的办法:设置struts2核心过滤器的参数。此处的配置大多都是固定的。       配置:在web.xml文件内的struts2核心过滤器的filter标签内进行配置。
           
              
struts-default.xml,struts-plugin.xml,Config/struts.xml
              /*
              蓝色字体:如果用了struts2-spring-plugin-2.3.24.jar包,就必须写。
              红色字体:自己指定的struts.xml的位置。
    4、优化:将applicationContext.xml的配置分开编写
       (1)创建application-customer.xml。配置和Customer相关的bean
              配置Service层和Dao层(略)
       (2)创建applicationContext-jdbc.xml。配置和JDBC相关的。
              配置HibernateTemplate,sessionFactory,dataSource(略)
       (3)创建applicationContext-tx.xml.配置和事务相关的。
              配置事务管理器,事务的通知,事务的aop(略)
       (4)最后将applicationContext.xml中的所有配置删除。只需要引入以上三
            个配置文件。
              写法:
                  
5、优化:将struts.xml的配置分开编写
       (1)创建struts-customer.xml。配置和Customer相关的动作。
              配置Action包中类的动作方法。(略)
              修改Action的继承包。
                  struts-default—myDefault
       (2)最后将struts.xml中关于动作方法的配置删除。
              配置开发者模式。
               配置公共包。公共的配置都写在struts.xml文件中。
                  
              引入其他的struts2的配置文件。
                  
    6、优化:使用HibernateDaoSupport。
       因为:如果有多个XXXDao类。那么以下代码就是重复代码。
           private HibernateTemplate hibernateTemplate;
        public void set HibernateTemplate(HibernateTemplate hibernateTemplate)         {
           this.hibernateTemplate=hibernateTemplate;
}
解决办法:Dao类继承HibernateDaoSupport。
          获取HibernateTemplate的方法:getHibernateTemplate();
配置:
1、在applicationContext-jdbc.xml中删除hibernateTemplate的配置。
    2、在applicationContext-customer.xml中修改Dao层的配置。
       
           
           
    7、优化:Spring接管Action的创建。
        (1)在applicationContext-customer.xml配置文件中,配置Action。
     (2)在struts-customer.xml配置文件中,修改原有的配置。
      将action标签的class属性值改为:customerAction。也就是Action的id
 
65.第三个版本的整合   代码实现:SSH03项目
    说明:其余的配置不再重复。此项目是基于SSH01的基础上作修改的。
1、优化:手动指定Spring配置文件applicationContext.xml的位置
       原因:Spring提供的ServletContext监听器会自动加载配置文件。
       解决的办法:设置ServletContext的初始化参数。来指定配置文件的位置。        配置:在web.xml文件内进行配置。
         
            
             
          
    2、使用注解配置Service层和Dao层和Action类,并删除相关的xml配置(略)
    3、在applicationContext.xml中配置Spring创建容器时要扫描的包(略)
    4、删除事务aop的xml配置,使用注解配置事务通知。(略)
    5、将Hibernate主配置文件中的内容都交给Spring来管理。(第二个版本有,此处略)
    6、删除实体类的映射配置文件,使用注解配置实体类。(JPA注解配置,此处略)
    7、修改applicationContext.xml中关于配置映射文件位置。
       配置:
              
    
       packagesToScan的作用:指定实体类所在的包,当创建SessionFactory,会去该
包中扫描实体类上的注解,从而生成映射配置。
    8、使用注解配置struts.xml配置文件的所有内容
       (1)导入jar包:struts2-convention-plugin-2.3.24.jar
       (2)删除struts.xml配置文件。
       (3)在Action类中使用注解配置动作方法和结果视图。
       (4)在web.xml中的filter标签内配置开发者模式和注解的位置
              开启开发者模式
                  
       
       
              指定注解的位置
              
    
    
 
 
      
   
