Spring - 图1

    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 - 图2
    Spring的IOC(XML版)
    6.搭建XML版的IOC开发环境
    (1)导入jar包
    Spring - 图3
    (2)在src创建bean.xml文件
    导入schema约束:Spring - 图4
    Spring - 图5
    7.Spring的入门案例
    ClassPathXmlApplicationContext 只能加载类路径下的配置文件
    FileSystemXmlApplicationContext 可以加载磁盘任意位置的配置文件
    1、获取容器
    ApplicationContext ac=new ClassPathXmlApplicationContext(“bean.xml”);
    2、根据bean的id获取类对象
    类名 变量名=(类名)ac.getBean(“”);
    需求: 通过bean配置文件,创建相应的类对象。
    代码实现:Spring1项目 IOCXML.Demo01

    8.Bean的两种创建规则
    Spring - 图6

    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)导包
    Spring - 图7
    (2)在src下创建bean.xml
    Spring - 图8

    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 - 图9
    第二步:把通知类交给spring来管理
    通知类:增强的代码

    第三步:导入AOP名称空间,并且使用aop:config开始AOP的配置 Spring - 图10
    第四步:使用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包
    Spring - 图11
    2、导入约束
    Spring - 图12
    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框架
    为我们提供了很多的操作模板类。
    Spring - 图13

    45.JdbcTemplate的基本用法(不使用配置文件bean.xml)
    代码实现:Spring5项目 JdbcTemplate.Demo01
    (1)导包
    Spring - 图14
    (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)导包
    Spring - 图15
    (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 rowMapper);
    query(String sql, RowMapper rowMapper,Object..params);
    参数:
    sql:不带参数的sql语句
    rowMapper:查询结果的结果集
    实现类:
    BeanPropertyRowMapper
    使用:
    new BeanPropertyRowMapper<类名>(类名.class)
    params:sql语句的参数值,按顺序赋值
    返回值:
    List
    2、查询一个
    同上。
    3、查询返回一行一列:聚合函数的使用
    方法:
    queryForObject(String sql,T.Class type,Object..params);
    (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包
    Spring - 图16
    (2)bean.xml文件导入约束
    Spring - 图17

    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层。
    只需要配置dataSource,不需要配置JdbcTemplate。
    第三步:配置Spring内置的DataSource(略)
    (4)基于XML的声明式事务控制
    第一步:配置事务管理器。



    第二步:配置事务的通知。(对应AOP的通知类)
    不需要配置切面AOP,Spring会自动提交和回滚事务。


    第三步:配置aop

    <!—切入点表达式 —>
    id=”pt1”>

    <!—配置事务通知和切入点表达式的关联 —>
    id”pointcut-ref=”切入点表达式的id”>

    第四步:配置事务的属性。在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层
    Spring - 图18
    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
    Spring - 图19
    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监听器
    Spring - 图20
    默认情况下:只能加载位置是在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的可选配置。因为都是键值对类型。
    使用标签和子标签,
    Spring - 图21
    (4)配置第三部分:映射文件的位置
    写法:


    XXXX


    name属性取值:
    mappingResources:它是一个注入String数组类型的数据。提供的是
    映射文件的位置。有几个映射文件,就需要写几个。
    mappingDirectoryLocations:它是注入一个Resource类型的数据。提供
    的是映射文件的目录。此属性一般多用于一个项目有多个地方存放映射配置。
    //服务端
    Server_domain
    //移动端
    Mobile_domain
    mappingLocations:它是注入一个Resource类型的数据。提供的是映射
    文件的位置。它可以使用通配符。
    配置:
    classpath:Domain/.hbm.xml
    2、优化:手动指定Spring配置文件applicationContext.xml的位置
    原因:Spring提供的ServletContext监听器会自动加载配置文件。
    解决的办法:设置ServletContext的初始化参数。来指定配置文件的位置。 配置:在web.xml文件内进行配置。

    contextConfigLocation
    classpath:Config/applicationContext.xml

    3、优化:手动指定Stuts2配置文件struts.xml的位置
    原因:struts2的核心过滤器会自动加载struts2的配置文件
    解决的办法:设置struts2核心过滤器的参数。此处的配置大多都是固定的。 配置:在web.xml文件内的struts2核心过滤器的filter标签内进行配置。

    config

    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文件中。
    abstract=”true”>
    引入其他的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文件内进行配置。

    contextConfigLocation
    classpath:Config/applicationContext.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标签内配置开发者模式和注解的位置
    开启开发者模式

    struts.devMode
    true

    指定注解的位置

    struts.convention.package.locators
    Action