spring框架 -业务层基于IDEA

1.spring框架共四天

第一天:spring框架的概述以及spring中基于XML的IOC配置

第二天:spring中基于注解的IOC和ioc的案例

第三天:spring中的aop和基于XML以及注解的AOP配置

第四天:spring中的JdbcTemlate以及Spring事务控制

1、spring的概述

​ spring是什么(了解)

Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

​ spring的两大核心:反转控制 AOP

​ spring的发展历程和优势

Rod Johnson ( spring 之父)

J2EE 开发不使用 EJB的解决方式(Spring 雏形)

2017 年 9 9 月份发布了 g spring 的最新版本 0 spring 5.0 通用版(GA)

spring 的优势

*方便解耦,简化开发*

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

*AOP 编程的支持*

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

*声明式事务的支持*

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

*方便程序的测试*

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

*方便集成各种优秀框架*

Spring可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。

*降低 JavaEE API 的使用难度*

Spring对 JavaEE API(如 JDBC、JavaMail、远程调用等)进行了薄薄的封装层,使这些 API 的使用难度大为降低。

*Java 源码是经典学习范例*

Spring的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对Java 设计模式灵活运用以及对 Java技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nKYjInYu-1600777672164)(C:\Users\wjq54\AppData\Roaming\Typora\typora-user-images\image-20200915095145868.png)]

2、程序的耦合及解耦

​ 曾经案例中问题

​ 工厂模式解耦

3、IOC概念和spring中的IOC

​ spring中基于XML的IOC环境搭建

​ 3.1spring 对bean的管理细节: 1,创建bean的三种方式。2.bean对象的作作用范围,3,bean的生命周期

3.1.1 创建三种bean的方式: 第一种:使用默认构造函数创建 。

在spring的配置文件中使用bean标签,配以id和class属性,且没有其他属性和变迁,采用的默认构造函数创建,如果类中没有默认构造函数,则对象无法创建

第二种方式:使用普通工厂的方法创建对象(使用某个类中的方法创建对象,并存入spring容器。

第三种方式:使用工厂中的静态方法创建对象

bean的作用范围调整:

bean的标签的scope属性:

作用:指定bean的作用范围

取值:常用就是单例和多例模式

singleton :单例(默认值) prototype 多例模式 request 作用web的请求范围 session 作用域web应用会话范围 gloable -session 作用集群环境的会话范围

bean对象的生命周期:

单例对象单例对象的生命周期和容器相同

多例对象:使用框架spring创建 ,在使用过程中一直存活, 当长时间不使用就死亡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9oUPhn1o-1600777672181)(C:\Users\wjq54\AppData\Roaming\Typora\typora-user-images\image-20200915191138807.png)]

/** * 获取spring的Ioc核心容器,并根据id获取对象 
*  ApplicationContext的三个常用实现类:
*    ClassPathXmlApplicationContext:它可以加载类路径下的配置文件,要求配置文件必须在类路径下。不在的话,加载不了。(更常用) 
*  FileSystemXmlApplicationContext:它可以加载磁盘任意路径下的配置文件(必须有访问权限)
* *     AnnotationConfigApplicationContext:它是用于读取注解创建容器的,是明天的内容。
* * 核心容器的两个接口引发出的问题:
*  ApplicationContext:     单例对象适用              采用此接口 
*      它在构建核心容器时,创建对象采取的策略是采用立即加载的方式。也就是说,只要一读取完配置文件马上就创建配置文件中配置的对象。
* *  BeanFactory:            多例对象使用 
*      它在构建核心容器时,创建对象采取的策略是采用延迟加载的方式。也就是说,什么时候根据id获取对象了,什么时候才真正的创建对象。
* @param args 
*/

配置bean.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       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">
    
    

4、依赖注入(Dependency Injection)

IOC的作用:降低程序间的耦合(依赖关系)

依赖关系的管理:交给spring管理,当前类需要到其他类的对象时候,由spring提供,只需要在配置文件说明依赖关系的维护,称为依赖注入。

依赖注入:能注入的数据分为三类 基本数据类型和string 其他bean类型 复杂数据类型/集合类型

注入的方式:1.构造函数,2.set提供 3.注解提供

构造函数的注入:

使用标签的:constructor-arg 标签出现的位置:bean标签的内部。 标签的属性:

   type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型      
 index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
 name:用于指定给构造函数中指定名称的参数赋值                                    以上三个用于指定给构造函数中哪个参数赋值     
 value:用于提供基本类型和String类型的数据       
 ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象 
 优势:在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。 
 弊端: 改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。

更常用的方式是-set-- 方法

涉及的标签是:property

复杂类型的注入/集合类型的注入

用于给list结构集合注入的标签 list array set

用于Map结构几个注入的标签map props

spring第二天:spring基于注解的IOC以及IoC的案例

1、spring中ioc的常用注解

2、案例使用xml方式和注解方式实现单表的CRUD操作

​ 持久层技术选择:dbutils

3、改造基于注解的ioc案例,使用纯注解的方式实现

​ spring的一些新注解使用

4、spring和Junit整合

曾经XML的配置:*  <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"*        scope=""  init-method="" destroy-method="">*      <property name=""  value="" | ref=""></property>*  </bean>
用于创建对象的
 *      他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的
 *      Component:
 *          作用:用于把当前类对象存入spring容器中
 *          属性:
 *              value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。
 *      Controller:一般用在表现层
 *      Service:一般用在业务层
 *      Repository:一般用在持久层
 *      以上三个注解他们的作用和属性与Component是一模一样。
 *      他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
 *
 *
 * 用于注入数据的
 *      他们的作用就和在xml配置文件中的bean标签中写一个<property>标签的作用是一样的
 *      Autowired:
 *          作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功
 *                如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
 *                如果Ioc容器中有多个类型匹配时:
 *          出现位置:
 *              可以是变量上,也可以是方法上
 *          细节:
 *              在使用注解注入时,set方法就不是必须的了。
 *      Qualifier:
 *          作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后我们讲)
 *          属性:
 *              value:用于指定注入bean的id。
 *      Resource
 *          作用:直接按照bean的id注入。它可以独立使用
 *          属性:
 *              name:用于指定bean的id。
 *      以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。
 *      另外,集合类型的注入只能通过XML来实现。
 *用于改变作用范围:scope value 有 singleton prototype(多对象)
 
  1.     <packaging>jar</packaging>
       
       <dependencies>
           <dependency>
               <!--springioc的一个容器,上下文,就像一个公司,下面很多有工厂-->
               <groupId>org.springframework</groupId>
               <artifactId>spring-context</artifactId>
               <version>5.0.2.RELEASE</version>
               
           </dependency>
           <dependency>
               <!--整合测试的包-->
               <groupId>org.springframework</groupId>
               <artifactId>spring-test</artifactId>
               <version>5.0.2.RELEASE</version>
           </dependency>
           <dependency>
               <groupId>commons-dbutils</groupId>
               <artifactId>commons-dbutils</artifactId>
               <version>1.4</version>
           </dependency>
       
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
               <version>8.0.18</version>
           </dependency>
    <!--连接池-->
            <dependency>
                <groupId>c3p0</groupId>
               <artifactId>c3p0</artifactId>
               <version>0.9.1.2</version>
           </dependency>
      
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.12</version>
           </dependency>
           <!--支持切入点表达式-->
           <dependency>
               <groupId>org.aspectj</groupId>
               <artifactId>aspectjweaver</artifactId>
               <version>1.8.7</version>
           </dependency>
           <!--事务-->
           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-tx</artifactId>
               <version>5.0.2.RELEASE</version>
           </dependency>
       </dependencies>
      
    //这个版本要4.12以上配置容器
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
            </dependency>
        </dependencies>
    jdbc:mysql://localhost:3306/my?serverTimezone=UTC
    

基于没有xml的配置需要采用创建一个类作用和bean.xml一样。spring新注解有

1.Configuration 当前类是一个配置类, 当AnnotationConfigApplicationContext对象创建参数就可以省略不写。

2.ComponentScan指定spring容器要扫描的包。和xml配<context:component-scan base-package=“com.itheima”></context:component-scan>相同

3.bean:把当前对象的返回值放入spring容器中。指定bean的id。当我们使用注解,里面有参数的话spring框架会去容器查找,查找的方式和Autowired注解作用一样

4.import导入其他配置类

PropertySource指定properties文件的位置 关键字classpath表示在类路径下

5

spring整合junit的配置

1.导入junit坐标,2.替换spring的@runwith 3,告诉spring运行器,是基于注解还是xml并说明位置,@ContextConfiguration location是xml。classpath是关键字表示在类路径下, classes是注解类所在的位置

动态代理:

特点:字节码随用随创建,随用随加载.对方法增强

分类:基于接口的动态代理 基于子类的动态代理

基于接口的动态代理:涉及的类Proxy 由JDK官方提供.使用Proxy类中的newProxyInstance方法,被代理的类最少实现一个接口.没有则不能使用使用

newProxyInstance方法的参数 :

classloader 类加载器 .加载代理对象字节码,和被代理对象使用相同的类加载器

Class[]字节码数组.它是用于让代理对象和被代理对象有相同方法

InvocationHander :用于提供增强的代码,此接口的实现类谁用谁写.

* @param proxy 代理对象的引用

​ * @param method 当前执行的方法

​ * @param args 当前执行方法所需的参数

​ * @return 和被代理对象方法有相同的返回值

基于子类的动态代理:

设计的类是Enhancer

提供者是第三方cglib库

如何创建代理对象:使用Enhance类的create方法 创建代理对象的要求,被代理类不能是最终类

create方法的参数:class方法的参数:class字节码 它是用于指定被代理对象的字节码.

Callback:用于增强的代码 他是让我们写如何代理,一般写该接口的子接口实现类.MethodInterceptor

//1.连接池.close不能真正的关闭,而是返回连接池中,采用动态代理的方法,对connection的cloase进行增强,把它放回到池中.// 解劝全栈的中文乱码问题

AOP : Aspect Oriented Programming :面向对象切面编程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iKMinSSP-1600777672215)(C:\Users\wjq54\AppData\Roaming\Typora\typora-user-images\image-20200919120826006.png)]

简单的说:把重复代码抽取出来,执行的时候,使用动态代理技术,不修改源码对已有的方法增强

AOP(掌握)

相关术语:Joinpint(连接点) 所谓连接点是指那些被拦截到的点,在spring中,这些点是指方法因为spring只支持方法类型的连接点

Pointcut(切入点):对哪些Joinpoint进行拦截的定义(被增强的那些方法)

Advice(通知/增强):通知拦截到Joinpoint之后的事情就是通知

通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知

Introduction(引介)引介是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类

动态添加一些成Filed或方法

Target(目标对象) 代理的目标对象;

Weaving(织入):把增强应用到目标对象来创建的代理对象的过程

spring是采用动态代理织入,而AspectJ采用编译期织入和类装载期织入

Proxy(代理)一个类被AOP织入增强就可能产生一个结果代表类

Aspect(切面)是切入点和通知(引介的结合)

学习spring中的aop明确做的事情

a开发阶段我们做的

编写核心业务代码(开发主线)大部分程序员来做,熟悉业务需求.

把公用的代码抽取出来,制作通知,(开发阶段最后来做)在配置文件中,声明切入点与通知之间的关系,即切面由Aop编程人员来做

b运行阶段

spring框架监控切入点方法的执行.一旦监控到切入点方法被执行,使用代理机制,动态的创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行

spring中基于xml的AOP的配置步骤

1,通知的bean交给spring来管理

2,使用aop:config标签表明开始Aop的配置------使用aop:aspect标签表明配置切面

(id 属性是给切面提供一个唯一标识 ) -------在aop:aspect标签内部使用对应的标签配置通知的类型

aop:before表示配置前置通知,method属性用于指定logger哪个方法是前置通知

pointcut属性:用于指定切入点表达式,表达式的含义指业务哪些方法增强

切入点表达式的写法:关键字execution表达式

表达式:

访问修饰符 返回值 包名 .包名. 包名…类名.方法名(参数列表)

标准的表达式写法:

public void com.itheima.service.impl.AccountServiceImpl.saveAccount()

访问修饰符可以省略

void com.itheima.service.impl.AcocuntServiceImpl.saceAccount()

返回值可以使用通配符,表达任意返回值

*b//com.itheima.impl.AccountServiceImpl.saveAccoutn();

包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.
                    * *.*.*.*.AccountServiceImpl.saveAccount())
                包名可以使用..表示当前包及其子包
                    * *..AccountServiceImpl.saveAccount()
                类名和方法名都可以使用*来实现通配
                    * *..*.*()
                参数列表:
                    可以直接写数据类型:
                        基本类型直接写名称           int
                        引用类型写包名.类名的方式   java.lang.String
                    可以使用通配符表示任意类型,但是必须有参数
                    可以使用..表示有无参数均可,有参数可以是任意类型
                全通配写法:
                    * *..*.*(..)

                实际开发中切入点表达式的通常写法:
                    切到业务层实现类下的所有方法
                        * com.itheima.service.impl.*.*(..)

            <aop:config>
    <!-- 配置切入点表达式 id属性用于指定表达式的唯一标识。expression属性用于指定表达式内容
          此标签写在aop:aspect标签内部只能当前切面使用。
          它还可以写在aop:aspect外面,此时就变成了所有切面可用
      -->
    <aop:pointcut id="pt1" expression="execution(* com.itheima.service.impl.*.*(..))"></aop:pointcut>
    <!--配置切面 -->
    <aop:aspect id="logAdvice" ref="logger">
        <!-- 配置前置通知:在切入点方法执行之前执行
        <aop:before method="beforePrintLog" pointcut-ref="pt1" ></aop:before>-->

        <!-- 配置后置通知:在切入点方法正常执行之后值。它和异常通知永远只能执行一个
        <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>-->

        <!-- 配置异常通知:在切入点方法执行产生异常之后执行。它和后置通知永远只能执行一个
        <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>-->

        <!-- 配置最终通知:无论切入点方法是否正常执行它都会在其后面执行
        <aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>-->


        <aop:around method="aroundPringLog" pointcut-ref="pt1"></aop:around>
    </aop:aspect>
</aop:config>

当配置环绕通知后,切入点方法没有执行,通知方法执行了,是因为动态代理有明确的切入点
spring框架为我们提供了一个接口,ProceedingPoint,该接口有一个方法procceed(),该方法明确调用切入点方法,该方法作为环绕通知的方法参数,spring框架为我们提供该接口的实现类为我们使用.
spring环绕通知:他是spring框架为我们提供一种可以在代码中手动控制何时增强的方式.
  Object[] args = pjp.getArgs();//得到方法执行所需的参数

            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置");

            rtValue = pjp.proceed(args);//明确调用业务层方法(切入点方法)

            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置");

            return rtValue;
 <!-- 配置spring创建容器时要扫描的包-->
    <context:component-scan base-package="com.itheima"></context:component-scan>

    <!-- 配置spring开启注解AOP的支持 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

spring 中的JdbcTemplate

作用:和数据库交互,实现对表CRUD的操作.

如何创建该对象

对象中常用的方法:

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/abc?serverTimezone=UTC"></property>
        <property name="user" value="root"></property>
        <property name="password" value="zp1536338"></property>
    </bean>
    
       <!--开启spring对注解AOP的支持-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

spring基于xml的声明式事务的控制步骤

配置事务管理器(DataSTractionManger----配置事务通知(transaction-manger)提供事务管理器引用)

—配置AOp的切入点表达式—建立事务通知和切入点表达式的对应关系–配置事务的属性在事务通知tx-advice标签内部

配置事物的属性:isolation :用于指定事务的隔离级别,表示使用数据库的默认隔离级别

propagation:用于指定事务的传播行为,表示一定会增删改的选择,默认值是REQUIRED表示一定会有事务,查询方法可以Support

read-only表示事务是否只读,只有查询方法才能设置为true,默认值是false

timeout-用于事务超时时间默认值是-1表示永不超时,如果制定了数值,则以秒为单位

rollback-for用于指定一个异常,当产生该异常事务回滚,产生其他的异常事务不回滚,咩有默认值,表示任何异常都会滚

no-rollback-for用于指定一个异常,当表示该异常,事物不回滚,产生其他异常事务回滚,没有默认值,表示任何异常都回滚.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
 @Autowired
需要的是读写型事务配置
 @Transactional(propagation = Propagation.REQUIRED,readOnly = false)
@Configuration
@ComponentScan("com.itheima")
@Import({JdbcConfig.class,TransactionConfig.class})
@PropertySource("jdbcConfig.properties")
@EnableTransactionManagement  
    

\1. PlatformTransactionManager

此接口是 spring 的事务管理器,它里面提供了我们常用的操作事务的方法,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZVhddXq-1600777672235)(file:///C:\Users\wjq54\AppData\Local\Temp\ksohtml13048\wps1.jpg)]

我们在开发中都是使用它的实现类,如下图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3WrCcV03-1600777672245)(file:///C:\Users\wjq54\AppData\Local\Temp\ksohtml13048\wps2.jpg)]

\2. TransactionDefinition

它是事务的定义信息对象,里面有如下方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QLxIROBs-1600777672255)(file:///C:\Users\wjq54\AppData\Local\Temp\ksohtml13048\wps3.jpg)]

*事务的隔离级别*

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TDHCaEXm-1600777672273)(file:///C:\Users\wjq54\AppData\Local\Temp\ksohtml13048\wps4.jpg)]

©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页