Spring

目录

1.Spring的概述

1.1 什么是Spring框架

1.2 为什么要使用Spring

1.3 IOC/DI概念

1.4 Spring的工厂类

1.5 Spring的入门(IOC)

2.Spring的配置

2.1 XML的提示配置

Schema的配置

2.2 Bean的相关的配置

2.3 Spring的分模块开发的配置

3.Spring的属性注入(非注解)

3.1 类成员变量常用的注入方式

3.2 Spring的2.5版本:p名称空间的注入

3.3 Spring的3.0版本:SpEL注入方式

3.4 集合(List,Set,Map),Properties等的注入

3.5 Spring自动装配Beans

 4.Spring的IOC的注解开发

4.1 Spring的IOC注解开发的快速入门

4.2 Spring的IOC注解的的详解

4.3Bean的作用范围和生命周期的注解

4.4 xml和注解整合开发

5.Spring的AOP的xml的开发

5.1 AOP的概述

5.2 Spring底层的AOP实现原理

 JDK的动态代理实现(代码了解,理解原理)

 CGLIB的代理技术实现(代码了解)

5.3 Spring基于AspectJ的AOP的开发

AOP的相关术语

5.4 Spring的AOP入门(AspectJ的XML方式)

5.5 Spring框架整合JUnit单元测试

5.6 AOP的通知类型

5.7 Spring的切入点表达式

6.Spring的AOP的基于AspectJ注解开发

6.1 Spring的基于ApsectJ的注解的AOP开发

6.2 Spring的注解的AOP的通知类型

7.Spring的JDBC的模板的使用

7.1 Spring框架的JDBC模板技术

7.2 JDBC模板使用的入门

7.3 将连接池和模板交给Spring管理

7.4 使用开源的数据库连接池

7.5 Spring框架的JDBC模板的简单操作

8.Spring的事务管理

8.1 事务的回顾

8.2 Spring的事务管理的API

8.3 Spring的事务的传播行为

8.4 Spring的事务管理

8.5 Spring的事务管理:编程式事务(了解)

8.6 Spring的事务管理:声明式事务管理

1.XML方式的声明式事务管理

2.注解方式的声明式事务管理


 

 

1.Spring的概述

1.1 什么是Spring框架

  • Spring是一个(以DI和AOP为核心)分层的JavaSE/EE一站式轻量级开源框架。
  • 一站式框架:有EE开发的每一层解决方案。
    • WEB层             :SpringMVC
    • Service层         :Spring的Bean管理,Spring声明式事务
    • DAO层              :Spring的Jdbc模板,Spring的ORM模块

Spring_第1张图片

1.2 为什么要使用Spring

1.方便解耦,简化开发

通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。有了Spring,用户不必再为单实例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

2.AOP编程的支持

通过Spring提供的AOP功能,方便进行面向切面的编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付。

3.声明式事务的支持

Spring中,我们可以从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量。

4.方便程序的测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,在Spring里,测试不再是昂贵的操作,而是随手可做的事情。例如:SpringJunit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架

Spring不排斥各种优秀的开源框架,相反,Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如mybatisHibernateJPAStrutsHessianQuartz)等的直接支持。

6.降低Java EE API的使用难度

Spring对很多难用的Java EE API(如JDBCJavaMail,远程调用等)提供了一个薄薄的封装层,通过Spring的简易封装,这些Java EE API的使用难度大为降低。

7.Java 源码是经典学习范例

Spring的源码设计精妙、结构清晰、匠心独运,处处体现着大师对Java设计模式灵活运用以及对Java技术的高深造诣。Spring框架源码无疑是Java技术的最佳实践范例。如果想在短时间内迅速提高自己的Java技术水平和应用开发水平,学习和研究Spring源码将会使你收到意想不到的效果。

1.3 IOC/DI概念

  • IOC: Inversion of Control(控制反转):不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。核心:bean工厂;Spring中,bean工厂创建的各个实例称作bean。所谓控制反转就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
  • DI:Dependency Injection:所谓依赖注入就是指:在运行期,由外部容器动态地将依赖对象注入到组件中。使用Spring我们不必在程序中维护对象的依赖关系,只要在XML中设定,Spring容器会自已根据相关的配置去产生他们之间的关系,相当于所有的关系都是在容器运行的时候注入的,而本身他们的关系是没有的
  • DI 相对 IoC 而言,明确描述了“被注入对象依赖 IoC 容器配置依赖对象”, 那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
  • IOC指导我们如何设计出松耦合、更优良的程序。

1.4 Spring的工厂类

Spring工厂类的结构图

Spring_第2张图片

1. ApplicationContext接口
    * 使用ApplicationContext工厂的接口,使用该接口可以获取到具体的Bean对象
    * 该接口下有两个具体的实现类
        * ClassPathXmlApplicationContext            -- 加载类路径下的Spring配置文件
        * FileSystemXmlApplicationContext            -- 加载本地磁盘下的Spring配置文件

2. BeanFactory工厂(是Spring框架早期的创建Bean对象的工厂接口)
    * 使用BeanFactory接口也可以获取到Bean对象

public void run(){
   BeanFactory factory = newXmlBeanFactory(newClassPathResource("applicationContext.xml"));
   UserService us = (UserService) factory.getBean("us");
   us.sayHello();
}

3. BeanFactory和ApplicationContext的区别
        * BeanFactory                  -- 调用getBean的时候,才会生成类的实例。
        * ApplicationContext        -- 加载配置文件的时候,就会将Spring管理的类都实例化。

1.5 Spring的入门(IOC)

步骤一:下载Spring框架的开发包
    * 官网:http://spring.io/
    * 下载地址:http://repo.springsource.org/libs-release-local/org/springframework/spring解压:(Spring目录结构:)

Spring_第3张图片
        * docs        -- API和开发规范
        * libs        -- jar包和源码
        * schema    -- 约束

步骤二:创建WEB项目,引入Spring的开发包
    * 根据Spring框架的体系结构图能看到,IOC核心功能需要引入如下的jar包
            * Beans
            * Core
            * Context
            * Expression Language
        Spring_第4张图片
        * Spring框架也需要引入日志相关的jar包
            * 在spring-framework-3.0.2.RELEASE-                          dependencies/org.apache.commons/com.springsource.org.apache.commons.logging/1.1.1
                * com.springsource.org.apache.commons.logging-1.1.1.jar
            * 还需要引入log4j的jar包 spring-framework-3.0.2.RELEASE-dependencies\org.apache.log4j\com.springsource.org.apache.log4j\1.2.15
                * com.springsource.org.apache.log4j-1.2.15.jar

步骤三:创建对应的包结构,编写Java的类
    * com.wyt.demo1
        * UserService            -- 接口
        * UserServiceImpl     -- 具体的实现类

步骤四:想把UserServiceImpl实现类的创建交给Spring框架来管理,需要创建Spring框架的配置文件,完成配置
    * 在src目录下创建配置文件applicationContext.xml(默认名称)的,名称是可以任意的
    * 引入spring的约束,需要先找到具体的约束头信息!!
        * spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html
        * 具体的约束如下:    
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-         beans.xsd">
            

    * 完成UserService的配置
        

6. 步骤五:编写测试类,采用Spring框架的工厂方式来获取到UserService接口的具体实现类
Spring_第5张图片

2.Spring的配置

2.1 XML的提示配置

Schema的配置

Spring_第6张图片

2.2 Bean的相关的配置

1. id属性和name属性的区别
    * id        --使用了约束中的唯一约束
        * 取值要求:必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号    id:不能出现特殊字符
    * name  -- 没有采用ID的约束
        * 取值要求:name:出现特殊字符.如果没有id的话 , name可以当做id使用
        * Spring框架在整合Struts1的框架的时候,Struts1的框架的访问路径是以/开头的,例如:/bookAction

2. class属性           -- Bean对象的全路径
3. scope属性          -- scope属性代表Bean的作用范围
    * singleton          -- 单例(默认值)
    * prototype         -- 多例模式。(Struts2和Spring整合一定会用到)
    * request            -- 应用在Web项目中,Spring创建这个类以后,将这个类存入到request范围中
    * session            -- 应用在Web项目中,Spring创建这个类以后,将这个类存入到session范围中
    * globalsession  -- 应用在Web项目中,必须在porlet环境下使用。但是如果没有这种环境,相对于session

4. Bean的生命周期的配置

  •   init-method :Bean被初始化的时候执行的方法
  •   destroy-method:Bean被销毁的时候执行的方法(环境条件:Bean是单例创建并且工厂关闭)

2.3 Spring的分模块开发的配置

1.在加载配置文件的时候,加载多个

2.在一个配置文件中引入多个配置文件

 

3.Spring的属性注入(非注解)

3.1 类成员变量常用的注入方式

1. 对于类成员变量,常用的注入方式有两种
    * 构造函数注入
    * 属性setter方法注入

2. 在Spring框架中提供了这两种的属性注入的方式
    1. 构造方法的注入方式,两步
        * 编写Java的类,提供构造方法

public class Car {
       private String name;
       private double money;
       public Car(String name, double money) {
             this.name = name;
             this.money = money;
       }
       @Override
       public String toString() {
             return "Car [name=" + name + ", money=" + money + "]";
       }
}


        * 编写配置文件

 
       
       


    2. 属性的setter方法的注入方式
        * 编写Java的类,提供属性和对应的set方法即可
        * 编写配置文件
    3. 如果Java类的属性是另一个Java的类,那么需要怎么来注入值呢?
        *

3.2 Spring的2.5版本:p名称空间的注入

1. 步骤一:需要先引入 p 名称空间
    * 在schema的名称空间中加入该行:xmlns:p="http://www.springframework.org/schema/p"

2. 步骤二:使用p名称空间的语法
    * p:属性名 = ""
    * p:属性名-ref = ""

3. 步骤三:测试
    *

3.3 Spring的3.0版本:SpEL注入方式

1. SpEL:Spring Expression Language是Spring的表达式语言,有一些自己的语法
2. 语法
    * #{SpEL}

Spring_第7张图片

3.4 集合(List,Set,Map),Properties等的注入


		
		
			
				王东
				赵洪
				李冠希
			
		
		
		
			
				李兵
				赵如何
				邓凤
			
		
		
		
			
				aaa
				bbb
				ccc
			
		
		
		
			
				
				
				
			
		
    		
                
                     
                         root
                         123
                     
                

3.5 Spring自动装配Beans

在Spring框架,可以用 auto-wiring 功能会自动装配Bean。要启用它,只需要在 定义“autowire”属性。

在Spring中,支持 5 自动装配模式。

  • no – 缺省情况下,自动配置是通过“ref”属性手动设定
  • byName – 根据属性名称自动装配。如果一个bean的名称和其他bean属性的名称是一样的,将会自装配它。
  • byType – 按数据类型自动装配。如果一个bean的数据类型是用其它bean属性的数据类型,兼容并自动装配它。
  • constructor – 在构造函数参数的byType方式。
  • autodetect – 如果找到默认的构造函数,使用“自动装配用构造”; 否则,使用“按类型自动装配”。

 

 

 4.Spring的IOC的注解开发

4.1 Spring的IOC注解开发的快速入门

1. 步骤一:导入注解开发所有需要的jar包
    * 引入IOC容器必须的6个jar包
    * Spring4版本多引入一个:spring-aop.jar
2. 步骤二:在src的目录下创建applicationContext.xml
    * 引入约束:使用注解开发需要引入context的约束,具体的约束如下
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
                http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd"> 
            
        

3. 步骤三:创建对应的包结构,编写Java的类
    * com.wyt.demo.UserService        -- 接口
    * com.wyt.demo.UserServiceImpl        -- 具体的实现类
4. 步骤四:在applicationContext.xml配置文件中开启组件扫描
    *
    * 注意:可以采用如下配置,就可以扫描com.wyt包下所有的内容
      
5. 步骤五:在UserServiceImpl的实现类上添加注解
    * @Component(value="userService")    -- 相当于在XML的配置方式中
6. 步骤六:编写测试代码
    public class SpringDemo1 {
        @Test
        public void run1(){
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService us = (UserService) ac.getBean("userService");
            us.save();
        }
    }

4.2 Spring的IOC注解的的详解

1. @Component:组件(修饰类,将这个类交给spring管理)

2. Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的)
    * @Controller        -- 作用在WEB层
    * @Service        -- 作用在业务层
    * @Repository        -- 作用在持久层
    * 说明:这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强

3. 属性注入的注解(说明:使用注解注入的方式,可以不用提供set方法)
    * 普通类型
        * @Value            -- 用于注入普通属性的值    
    * 对象类型属性
        * @Autowired        -- 设置对象类型的属性的值,按照类型进行自动装配
        * 如果想按名称完成属性注入,要让@Autowired和@Qualifier结合使用
    * @Resource
        * 按照名称完成属性注入,相当于@Autowired和@Qualifier一起使用        
        * 强调:Java提供的注解
        * 属性使用name属性


4.3Bean的作用范围和生命周期的注解

1. Bean的作用范围注解
    * 注解为@Scope(value="prototype"),作用在类上。值如下:
        * singleton        -- 单例,默认值
        * prototype        -- 多例

2. Bean的生命周期的配置(了解)
    * 注解如下:
        * @PostConstruct    -- 相当于init-method
        * @PreDestroy        -- 相当于destroy-method


4.4 xml和注解整合开发

xml管理Bean,注解完成属性注入
1.将所有的bean都配置xml中
       
2.将所有的依赖都使用注解
       @Autowired        
       默认不生效。为了生效,需要在xml配置:
总结:
注解1:扫描指定包下类上标有@Service,@Component,@Repository,@Controller注解的全部类,并注册成bean
注解2:打开注解开关,激活那些已经在spring容器里注册过的bean,来完成属性注入的注解:@Resource、@value、@Autowired、@Qulifier,一般情况两个注解不一起使用。

5.Spring的AOP的xml的开发

5.1 AOP的概述

     AOP全称:Aspect-Oriented Programming,面向切面编程。可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。

     AOP,面向切面编程,就是把可重用的功能提取出来,然后将这些通用功能在合适的时候织入到应用程序中,比如事务管理权限控制日志记录、性能统计等,AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码。

    AOP并没有帮助我们解决任何新的问题,它只是提供了一种更好的办法,能够用更少的工作量来解决现有的一些问题,使得系统更加健壮,可维护性更好。

5.2 Spring底层的AOP实现原理

1. 采用动态代理技术,代理的方式提供了两种
    1. 基于JDK的动态代理
        * 只能对实现了接口的类产生代理
    2. 基于Cglib动态代理
        * 对于没有实现接口的类产生代理对象,生成子类对象
2. Spring的底层AOP中根据类是否实现接口,来采用不同的代理方式
    1. 如果实现类接口,使用JDK动态代理完成AOP
    2. 如果没有实现接口,采用CGLIB动态代理完成AOP

 JDK的动态代理实现(代码了解,理解原理)

使用Proxy类来生成代理对象的一些代码如下:

public class MyProxyUtils {
        public static UserDao getProxy(final UserDao dao) {
            // 使用Proxy类生成代理对象
            UserDao proxy = (UserDao) Proxy.newProxyInstance(dao.getClass().getClassLoader(),
                    dao.getClass().getInterfaces(), new InvocationHandler() {
                        
                        // 代理对象方法一直线,invoke方法就会执行一次
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            if("save".equals(method.getName())){
                                System.out.println("记录日志...");
                                // 开启事务
                            }
                            // 提交事务
                            // 让dao类的save或者update方法正常的执行下去
                            return method.invoke(dao, args);
                        }
                    });
            // 返回代理对象
            return proxy;
        }
    }

 CGLIB的代理技术实现(代码了解)

CGLIB是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口
1. 引入CBLIB的开发包
    * 在Spring框架核心包中已经引入了CGLIB的开发包了。所以直接引入Spring核心开发包即可!
2. 编写相关的代码

  public static OrderDaoImpl getProxy(){
        // 创建CGLIB核心的类
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(OrderDaoImpl.class);
        // 设置回调函数
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args,
                    MethodProxy methodProxy) throws Throwable {
                if("save".equals(method.getName())){
                    // 记录日志
                    System.out.println("记录日志了...");
                }
                return methodProxy.invokeSuper(obj, args);
            }
        });
        // 生成代理对象
        OrderDaoImpl proxy = (OrderDaoImpl) enhancer.create();
        return proxy;
    }


5.3 Spring基于AspectJ的AOP的开发

Spring早期AOP的实现非常繁琐。AspectJ是一个面向切面(AOP)的框架,Spring引入AspectJ作为自身AOP的开发。

AOP的相关术语

1. Joinpoint(连接点)    -- 所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点
2. Pointcut(切入点)        -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
3. Advice(通知/增强)    -- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
4. Introduction(引介)    -- 引介是一种特殊的通知在不修改类代码的前提下, Introduction可以在运行期为类动态地添加一些方法或Field
5. Target(目标对象)        -- 代理的目标对象
6. Weaving(织入)        -- 是指把增强应用到目标对象来创建新的代理对象的过程
7. Proxy(代理)        -- 一个类被AOP织入增强后,就产生一个结果代理类
8. Aspect(切面)            -- 是切入点和通知的结合,以后供自己来编写和配置的

5.4 Spring的AOP入门(AspectJ的XML方式)

1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包
    * 先引入Spring框架开发的基本开发包
    * 再引入Spring框架的AOP的开发包
        * spring的传统AOP的开发的包
            * spring-aop-4.2.4.RELEASE.jar
            * com.springsource.org.aopalliance-1.0.0.jar(aop联盟包)
        * aspectJ的开发包
            * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
            * spring-aspects-4.2.4.RELEASE.jar

2. 步骤二:创建Spring的配置文件,引入具体的AOP的schema约束
                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.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

3. 步骤三:创建包结构,编写具体的接口和实现类
    * com.wyt.demo
        * CustomerDao            -- 接口
        * CustomerDaoImpl        -- 实现类

4. 步骤四:将目标类配置到Spring中
    

5. 步骤五:定义切面类
    public class MyAspectXml {
        // 定义通知
        public void log(){
            System.out.println("记录日志...");
        }
    }

6. 步骤六:在配置文件中定义切面类
    

7. 步骤七:在配置文件中完成aop的配置
    
        
        
            
            
        

    

8. 完成测试
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class Demo3 {
        @Resource(name="customerDao")
        private CustomerDao customerDao;
        @Test
        public void run1(){
            customerDao.save();
            customerDao.update();
            customerDao.delete();
        }
    }

5.5 Spring框架整合JUnit单元测试

1. 为了简化了JUnit的测试,使用Spring框架也可以整合测试
2. 具体步骤
    * 要求:必须先有JUnit的环境(即已经导入了JUnit4的开发环境)!!
    * 步骤一:在程序中引入:spring-test.jar
    * 步骤二:在具体的测试类上添加注解
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration("classpath:applicationContext.xml")
        public class SpringDemo1 {
            @Resource(name="userService")
            private UserService userService;      
            @Test
            public void demo2(){
                userService.save();
            }
        }


5.6 AOP的通知类型

1. 前置通知
    * 在目标类的方法执行之前执行。
    * 配置文件信息:
    * 应用:可以对方法的参数来做校验
2. 后置通知
    * 方法正常执行后的通知。        
    * 在配置文件中编写具体的配置:
    * 应用:可以修改方法的返回值
3. 环绕通知
    * 方法的执行前后执行。
    * 在配置文件中编写具体的配置:
    * 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。
4. 异常抛出通知
    * 在抛出异常后通知
    * 在配置文件中编写具体的配置:    
    * 应用:包装异常的信息

5. 最终通知
    * 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
    * 在配置文件中编写具体的配置:
    * 应用:例如像释放资源


5.7 Spring的切入点表达式

    * 切入点表达式的格式如下:
        * execution([修饰符] 返回值类型 包名.类名.方法名(参数))
    * 修饰符可以省略不写,不是必须要出现的。
    * 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
    * 包名例如:com.wyt.demo3.BookDaoImpl
        * 首先com是不能省略不写的,但是可以使用 * 代替
        * 中间的包名可以使用 * 号代替
        * 如果想省略中间的包名可以使用 .. 
    * 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
    * 方法也可以使用 * 号代替
    * 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..

6.Spring的AOP的基于AspectJ注解开发


6.1 Spring的基于ApsectJ的注解的AOP开发

1. 步骤一:创建JavaWEB项目,引入具体的开发的jar包
    * 先引入Spring框架开发的基本开发包
    * 再引入Spring框架的AOP的开发包
        * spring的传统AOP的开发的包
            * spring-aop-4.2.4.RELEASE.jar
            * com.springsource.org.aopalliance-1.0.0.jar
        
        * aspectJ的开发包
            * com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
            * spring-aspects-4.2.4.RELEASE.jar
2. 步骤二:创建Spring的配置文件,引入具体的AOP的schema约束
                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.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
        
    

3. 步骤三:创建包结构,编写具体的接口和实现类
    * com.itheima.demo1
        * CustomerDao            -- 接口
        * CustomerDaoImpl        -- 实现类
4. 步骤四:将目标类配置到Spring中
    
5. 步骤五:定义切面类
    * 添加切面和通知的注解
        * @Aspect                    -- 定义切面类的注解
        
        * 通知类型(注解的参数是切入点的表达式)
            * @Before                -- 前置通知
            * @AfterReturing        -- 后置通知
            * @Around                -- 环绕通知
            * @After                -- 最终通知
            * @AfterThrowing        -- 异常抛出通知
    
    * 具体的代码如下
        @Aspect
        public class MyAspectAnno {
            @Before(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
            public void log(){
                System.out.println("记录日志...");
            }
        }

6. 步骤六:在配置文件中定义切面类
    

7. 步骤七:在配置文件中开启自动代理
    

8. 完成测试
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class Demo1 {
        
        @Resource(name="customerDao")
        private CustomerDao customerDao;
        
        @Test
        public void run1(){
            customerDao.save();
            customerDao.update();
        }
    }

6.2 Spring的注解的AOP的通知类型

1. 通知类型
    * @Before                -- 前置通知
    * @AfterReturing        -- 后置通知
    * @Around            -- 环绕通知(目标对象方法默认不执行的,需要手动执行)
    * @After            -- 最终通知
    * @AfterThrowing        -- 异常抛出通知

2. 配置通用的切入点
    * 使用@Pointcut定义通用的切入点
    
    @Aspect
    public class MyAspectAnno {
        @Before(value="MyAspectAnno.fn()")
        public void log(){
            System.out.println("记录日志...");
        }
        @Pointcut(value="execution(public void com.itheima.demo1.CustomerDaoImpl.save())")
        public void fn(){}
    }

7.Spring的JDBC的模板的使用

7.1 Spring框架的JDBC模板技术

1. Spring框架中提供了很多持久层的模板类来简化编程,使用模板类编写程序会变的简单
2. 提供了JDBC模板,Spring框架提供的
    * JdbcTemplate类
3. Spring框架可以整合Hibernate框架,也提供了模板类
    * HibernateTemplate类

7.2 JDBC模板使用的入门

1. 步骤一:创建数据库的表结构
    create database spring_day03;
    use spring_day03;
    create table t_account(
        id int primary key auto_increment,
        name varchar(20),
        money double
    );

2. 引入开发的jar包
    * 先引入IOC基本的6个jar包
    * 再引入Spring-aop的jar包
    * 最后引入JDBC模板需要的jar包
        * MySQL数据库的驱动包
        * Spring-jdbc.jar
        * Spring-tx.jar

3. 编写测试代码(自己来new对象的方式)
    @Test
    public void run1(){
        // 创建连接池,先使用Spring框架内置的连接池
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///spring_day03");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        // 创建模板类
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        // 完成数据的添加
        jdbcTemplate.update("insert into t_account values (null,?,?)", "测试",10000);
    }


7.3 将连接池和模板交给Spring管理

1. 刚才编写的代码使用的是new的方式,应该把这些类交给Spring框架来管理。
2. 修改的步骤如下
    * 步骤一:Spring管理内置的连接池
        
            
            
            
            
        

    
    * 步骤二:Spring管理模板类
        
            
        

    
    * 步骤三:编写测试程序
        @RunWith(SpringJUnit4ClassRunner.class)
        @ContextConfiguration("classpath:applicationContext.xml")
        public class Demo2 {
            
            @Resource(name="jdbcTemplate")
            private JdbcTemplate jdbcTemplate;
            
            @Test
            public void run2(){
                jdbcTemplate.update("insert into t_account values (null,?,?)", "测试2",10000);
            }
        }


7.4 使用开源的数据库连接池

1. 管理DBCP连接池
    * 先引入DBCP的2个jar包
        * com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
        * com.springsource.org.apache.commons.pool-1.5.3.jar
    * 编写配置文件
        
            
            
            
            
        

2. 管理C3P0连接池
    * 先引入C3P0的jar包
        * com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar
    * 编写配置文件
        
            
            
            
            
        


7.5 Spring框架的JDBC模板的简单操作

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class SpringDemo3 {    
        @Resource(name="jdbcTemplate")
        private JdbcTemplate jdbcTemplate;
        
        @Test
        // 插入操作
        public void demo1(){
            jdbcTemplate.update("insert into account values (null,?,?)", "冠希",10000d);
        }
        
        @Test
        // 修改操作
        public void demo2(){
            jdbcTemplate.update("update account set name=?,money =? where id = ?", "思雨",10000d,5);
        }
        
        @Test
        // 删除操作
        public void demo3(){
            jdbcTemplate.update("delete from account where id = ?", 5);
        }
        
        @Test
        // 查询一条记录
        public void demo4(){
            Account account = jdbcTemplate.queryForObject("select * from account where id = ?", new BeanMapper(), 1);
            System.out.println(account);
        }
        
        @Test
        // 查询所有记录
        public void demo5(){
            List list = jdbcTemplate.query("select * from t_account", new BeanMapper());
            for (Account account : list) {
                System.out.println(account);
            }
        }
    }
    
    class BeanMapper implements RowMapper{
        public Account mapRow(ResultSet rs, int arg1) throws SQLException {
            Account account = new Account();
            account.setId(rs.getInt("id"));
            account.setName(rs.getString("name"));
            account.setMoney(rs.getDouble("money"));
            return account;
        }
    }

 

8.Spring的事务管理

8.1 事务的回顾

1. 事务概述:

事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。这样可以防止出现脏数据,防止数据库数据出现问题。

开发中为了避免这种情况一般都会进行事务管理。

 Spring的声明式事务通常是指在配置文件中对事务进行配置声明,其中包括了很多声明属性,它是通过Spring Proxy帮你做代理,自己不用额外的写代码,只要在Spring配置文件中声明即可;通常用在数据库的操作里面;

 编程式事务就是指通过硬编码的方式做事务处理,这种处理方式需要写代码,事务中的逻辑可以自己定制;可以是数据库的东东,也可以是其他的操作。

 Spring中也有自己的事务管理机制,一般是使用TransactionMananger进行管理,可以通过Spring的注入来完成此功能。

2. 事务的特性

ACID,指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

  • 原子性:事务不可分割
  • 一致性:事务执行前后数据完整性保持一致
  • 隔离性:一个事务的执行不应该受到其他事务的干扰
  • 持久性:一旦事务结束,数据就持久化到数据库

3. 如果不考虑隔离性,引发安全性问题 

读问题

  • 脏读:一个事务读到另一个事务未提交的数据
  • 不可重复读:一个事务读到另一个事务已经提交的update的数据,导致一个事务中多次查询结果不一致
  • 虚读、幻读:一个事务读到另一个事务已经提交的insert的数据,导致一个事务中多次查询结果不一致。

写问题

  • 丢失更新

4. 如何解决安全性问题

* 读问题解决,设置数据库隔离级别
  • Read uncommitted :未提交读,任何读问题解决不了。
  • Read committed      :已提交读,解决脏读,但是不可重复读和虚读有可能发生。
  • Repeatable read      :重复读,解决脏读和不可重复读,但是虚读有可能发生。
  • Serializable                :解决所有读问题。

* 写问题解决可以使用 悲观锁和乐观锁的方式解决

8.2 Spring的事务管理的API

 1. PlatformTransactionM anager:平台事务管理器

平台事务管理器:接口,是Spring用于管理事务的真正的对象。

  • Dat aSourceTransactionManager  :底层使用JDBC管理事务
  • HibernateTransactionManager       :底层使用Hibernate管理事务

2.TransactionDefinition   :事务定义信息

  • 事务定义:用于定义事务的相关的信息,隔离级别、超时信息、传播行为、是否只读

3.TransactionStatus:事务的状态

  • 事务状态:用于记录在事务管理过程中,事务的状态的对象。

4.事务管理的API的关系: 

Spring进行事务管理的时候,首先平台事务管理器根 据事务定义信息进行事务的管理,在事务管理过程中,产生各种状态,将这些状态的信息记录到事务状态的对象中。 

8.3 Spring的事务的传播行为

Spring中提供了七种事务的传播行为:

         保证多个操作在同一个事务中

  • PROPAGATION_MANDATORY:如果A中有事务,使用A中的事务。如果A没有事务,抛出异常。
  • PROPAGATION_SUPPORTS:支持事务,如果A中有事务,使用A中的事务。如果A没有事务,不使用事务。
  • PROPAGATION_REQUIRED:默认值,如果A中有事务,使用A中的事务,如果A没有,创建一个新的事务,将操作包含进来

       保证多个操作不在同一个事务中

  • PROPAGATION_REQUIRES_NEW:如果A中有事务,将A的事务挂起(暂停),创建新事务,只包含自身操作。如果A中没有事务,创建一个新事务,包含自身操作。
  • PROPAGATION_NOT_SUPPORTED:如果A中有事务,将A的事务挂起。不使用事务管理。
  • PROPAGATION_NEVER:如果A中有事务,报异常。

      嵌套式事务

  • PROPAGATION_NESTED:嵌套事务,如果A中有事务,按照A的事务执行,执行完成后,设置一个保存点,执行B中的操作,如果没有异常,执行通过,如果有异常,可以选择回滚到最初始位置,也可以回滚到保存点。

8.4 Spring的事务管理

搭建Spring的事务管理的环境

1.创建Service的接口和实现类

Spring_第8张图片

2.创建DAO的接口和实现类

Spring_第9张图片

 

3.配置Service和DAO:交给Spring管理

Spring_第10张图片

 

4.在DAO中编写扣钱和加钱方法:

配置连接池和JDBC的模板

Spring_第11张图片

 

在DAO注入Jdbc的模板:

8.5 Spring的事务管理:编程式事务(了解)

第一步:配置平台事务管理器

第二步:Spring提供了事务管理的模板类

 

配置事务的管理的模板类

第三步:在业务层注入事务管理的模板

Spring_第12张图片

第四步:编写事务管理的代码

Spring_第13张图片

8.6 Spring的事务管理:声明式事务管理

1.XML方式的声明式事务管理

  • 第一步:引入aop的开发包
  • 第二步:恢复转账环境
  • 第三步:配置事务管理器

  • 第四步:配置增强

Spring_第14张图片

  • 第五步:AOP的配置

2.注解方式的声明式事务管理

  • 第一步:引入aop的开发包
  • 第二步:恢复转账环境
  • 第三步:配置事务管理器

  • 第四步:开启注解事务

  • 第五步:在业务层添加注解

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(BasicHome)