1、什么是spring?

  • 老规矩:百度百科一手

  • 这上面说得太多了,我来提炼一下:

    • spring就是一个轻量级的控制反转( IOC ) 和 面向切面编程( AOP ) 的容量框架。总的来说:本质就是对java三层架构中service层的处理框架

    • spring的优点:

      • 免费、非入侵式、轻量级( 占据内存小呗 )的框架
      • 有控制反转( IOC ) 和 面向切面编程( AOP )
      • 支持对事务的处理、支持和另外框架整合

2、IOC思想

  • 原始开发中,在一个类中需要调用另一个类中的方法是怎么做的?

1)、什么是IOC思想?

  • 简单得很。IOC就是指:对象的创建从主动变为了别动。详细点来说就是:从前一个类要依赖于另一个类的对象时,我们只能在类中new出来,从而才可以去进行调用那个类中的方法,不new的话去调用会产生空指针异常的,如:

  • 而IOC的意思就是:这个new对象的过程不需要我们程序员自己创建,由Ioc容器帮我们创建,我们只需要把Ioc容器帮忙创建的对象拿来用就行了( 当然:在spring中是需要我们去指定要那个对象,后续说明 ),因此:IOC思想就是把对象的创建由我们程序员自己创建变成了Ioc容器帮我们创建而已,这个主动权不在我们程序员手里了,这就是:控制反转思想,即:IOC思想 , 这反转就是对象的创建方式发生了反转而已,而正转就是我们以前new的那种方式 )

2)、那在spring中怎么实现这种IOC思想呢?

  • 老规矩,看官网,spring官网如下:

    • https://spring.io/

    • 看不懂英文?那就给浏览器整一个翻译插件( 我的是微软的Edge浏览器)

(1)、对spring的IOC快速上个手,直接看官网

  • 官网不道德啊,我找不到和要导入的jar包相关的内容了

    • 因此:第一步我来说一下,玩IOC需要什么jar包

      • 建好maven项目,导入如下的一个jar包
        <!--
spring-webmvc 是springMVC的包( 这是接下来的一个框架 )
springMVC是spring的一个点,因此:玩spring用这个包也可以
但是:纯的spring包是:spring-context
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency> <!--spring-context包 使用这两个中的其中一个都可以-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>

  • 体验一下:IOC

    • 1、建一个类

    • 2、编写配置文件:来喵官网

    • 3、测试

3、spring是怎么做到帮我们创建对象的? ———— DI 依赖注入

  • 瞄一下官网,什么是DI

    • 官网上面说得很抽象、很笼统,看不太懂,因此:我来说一下:

      • DI,即:依赖注入,全称:Dependency Injection。所谓的DI就是IOC思想的一种实现方式,IOC其实是一种思想,它自己并不能帮我们创建对象,而是需要通过DI来帮忙实现,这个DI是怎么实现IOC控制反转的?即:上图中说到的那两个原理,一是看要创建的类有没有无参构造,如果有,那么就通过无参构造来创建对象,从而实现了IOC思想,即:控制反转( 对于我们来说:对象的创建由主动变为了被动接收spring提供的对象 );二是如果要创建的类没有无参构造( 即:被有参构造覆盖了 ),那么就看这个类有没有setter方法,然后通过setter方法来帮我们创建这个类的对象( 底层是获取setter方法的方法名,从而把set截掉,就得到了后缀名,这个后缀名对应的就是属性名的类型嘛,从而这个属性就有对象了嘛( 就是一个类中引用了另一个的对象来当做自己的属性 那么这个属性就是另一个类的对象涩,这样注入的这个属性就成了另一个类的对象嘛,这一个参照前面说的那个IOC思想的引进,图如下: )

1)、那么怎么来玩DI依赖注入

(1)、基于无参构造的注入

  • 导包,建类

  • 玩DI注入

  • 测试

  • 小拓展一下:既然这种是基于无参构造来玩的,那么我不提供无参构造呢?

    • 因此:用无参构造来让spring帮忙创建对象,那么必须要有无参构造,不然:报初始化错误

(2)、基于setter方法的注入( 即:没有无参构造时 ) —— 后面这几种了解即可,需要时知道有这么一个玩法就行

  • ①、通过下标赋值

  • 建类

  • 对象托管

  • 测试

  • ②、通过属性名赋值

    • 建类

    • 对象托管

    • 测试

  • 通过类的类型 了解中的了解

    • 建类

    • 对象托管

    • 测试

(3)、玩了上面这些之后,spring的IOC就玩的差不多了,现在来玩一下IOC的最后一个点:DI支持哪些类型的注入? —— 了解即可吧

  • 建类( get / set方法自行补充 )

  • 对象托管,完成属性对象的依赖注入

<!--    完成对各种类型的属性对象依赖注入-->
<bean id="typeOfDI" class="cn.xieGongZi.entity.TypeOfDI"> <!-- 普通类型注入-->
<property name="id" value="1"/> <!-- 数组类型注入-->
<property name="hobbys">
<array>
<value>敲代码</value>
<value>嫖娼</value>
<value>敲板砖</value>
</array>
</property> <!-- list类型-->
<property name="dis">
<list>
<value>111</value>
<value>333</value>
<value>555</value>
</list>
</property> <!-- set类型-->
<property name="baseSetters">
<set>
<value>张三</value>
<value>李四</value>
</set>
</property> <!-- map类型-->
<property name="wife">
<map>
<entry key="1" value="苍老师"/>
<entry key="2" value="波多野结衣"/>
</map>
</property> <!-- 引用类型( 这个引用是指的自己建的类 类型 )-->
<property name="di" ref="di"/> <!-- properties类型-->
<property name="info">
<props>
<prop key="1">不知道</prop>
<prop key="1">皮包骨</prop>
</props>
</property>
</bean>
  • 测试

4、单例模式和工厂模式

  • 回顾一下:设计模式有哪几种

  • 刚刚在前面快速上手那里,两个对象是相同的,因此:得出spring底层创建对象是用到了单例模式,而且是我们用的时候才创建的,因此:就是单例模式的懒汉式加载。当然单例模式我这里不做演示了,在我的javaSE的工具类篇中的Runtime类时说明过单例模式(我这里面是简化版,是为了好理解思路而已,优化版需要考虑线程的问题和对象为不为null【 即:一开始有没有对象,有就用,没有才创建 】 )

  • 1)、工厂模式 —— spring为什么可以帮我们创建对象?

    • (1)、简单工厂 / 静态工厂,就是有static和没有的区别而已

      • 原生的方式创建对象

      • 改造,成为简单工厂

        • 但是:这种简单工厂违背了设计原则 开闭原则。我博客的原则解读说明如下:

      • (2)、工厂方法模式:就是稍微变了一下

        • 现在的结构就变成了下面这样

      • 因此:工厂方法模式也不好,对于各个方面来说( 代码的复杂度.... )都没有简单工厂好,虽然简单工厂违背了原则,但是它在各个方面都完胜,因此:违背就违背嘛,当前场景最适合更好,所以:设计原则并不是一定需要准守的,只要适合就行

      • 有了上述的两个设计模式之后,spring底层帮忙创建对象的原理就知道了,把哪个传递进去的水果名字改成配置文件名字,然后利用反射创建对象不就完了吗

5、spring的自动装配

  • 自动装配是什么意思?

    • 就是spring根据Context容器自动帮我们去识别类中的属性是哪一个
  • 1)、体验一下ByName自动装配Bean

    • 先来看一下没有自动装配之前的玩法

    • 有了自动装配之后

      • 深入理解一下byName

    • 2)、体验一下ByType自动装配Bean

      • 把如下这里改一下就可以了

        • 但是:这个byType的原理和byName不一样

自此:spring的IOC思想就完了,其他没提到的,需要时自行摸索吧,如:p 和 c命名空间依赖、import导入多人的配置文件( 注解版这里面不说明,等到springBoot再玩 )

6、spring的AOP切面编程

  • 再玩这个之前:来玩一个设计模式 —— 代理模式

    • 1)、静态代理

      • 假如自己要租房子,所以自己就要找房子,也就需要找房东,但是:房东不会直接带你去看房子、签合同之类的,而是由中介带你看房子,然后签订合同

      • 用代码演示一下

这就是静态代理,但是:啥事都有优点和缺点嘛

  • 优点:

    • 业务的分工更明确
    • 公共部分抽取出来之后更方便管理,只要添加相应的公共部分,代理就会很容易更新
  • 缺点:

    • 每有一个被代理角色,就会有一个代理角色,即:代码量会很大

2)、动态代理

- 动态代理就是:动态地生成一个代理嘛。前面那个静态代理我们是直接写了一个proxy,把代理写死的

  • 动态代理也有四个角色:真实角色、被代理角色、代理角色、抽象角色

  • 实现动态代理的方式很多:可以分为 接口式( 重点,JDK自带的 )、类cglib( 这里不说明 )、使用javasist( 这个在JBoss服务器中有 )

    • 玩一下接口式,在玩这个之前,来了解两个类:Proxy 和 InvocationHandler

  • 玩一下动态代理


package dynamicProxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; // 不是说的每一个代理类都有一个调用处理程序吗 —— 建一个
// 不能自己说自己是代理的调用处理程序 自己就是涩
// 实现InvocationHandler
public class ProxyInvocationHandler implements InvocationHandler { // 动态代理的公式 // 1、要代理的是谁? ———— 真实角色
public Object target; public void setTarget(Object target) {
this.target = target;
} // 2、动态生成代理
// 怎么生成代理 ———— 官网中有涩
/*
* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class<?>[] { Foo.class },
handler );
*/
// 那就来嘛 注意:java.lang.reflect.Proxy 是这个包下的,别搞错了
public Object getProxy() { return Proxy.newProxyInstance( this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); /*
* this.getClass().getClassLoader() 指的是:获取代理类的反射对象嘛
* target.getClass().getInterfaces() 指的是:获取要代理的对象的接口嘛
* this 这就是需要一个处理器嘛 我们当前类不就是处理器吗
* */
} // 3、执行代理角色接口中的方法嘛 ———— 反射涩
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke( target,args ); /*
* target 执行的是哪个接口中的方法 代理对象涩( 即:抽象角色嘛 )
* args 这是一个Object...args 就是获取接口中方法的参数嘛
* */ }
}
  • 测试

6.1、spring的AOP切面编程

在玩AOP之前还需要知道一些理论知识:AOP的术语知识

  • 看不懂?更没事儿,直接上代码,然后回过来看就知道了

  • 1)、准备工作:导入依赖


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency> <!-- AOP必需的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!-- AOP用这个织入包也可以 -->
<!-- <dependency>-->
<!-- <groupId>org.aspectj</groupId>-->
<!-- <artifactId>aspectjweaver</artifactId>-->
<!-- <version>1.8.10</version>-->
<!-- </dependency>--> <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
  • 2)、编写spring的配置文件

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

  • 3)、编写类,用来测试嘛

  • 4)、那就需要一个切入的内容嘛,建一个

  • 5)、把类进行对象托管、并通过AOP实现信息的插入

  • 6)、测试

整个过程( 包括测试的地方 )结合动态代理模式更容易理解 ———— AOP也是spring的一个小难点,其实也很好理解

  • 就好比:给项目新加功能,不能把别人的源代码给改动了涩,我们要新增功能就只能在原有代码的基础上,添加东西即可( 注:我这里说的不改动源代码是说的别人写好的代码我们不动,但是在别人写好的源代码中我们可以加入代码,不然钻入牛角尖了【 表达暂时就这样,词穷了 】 ),如:

现在再来看下图的内容就很好理解了

另外:示例用的通知类是methodBeforeAdvice,那肯定就有其他的了,如下( 例子自行演示 ):


前置通知:MethodBeforeAdvice
后置通知:AfterAdvice 这个是父类,子类有AfterReturningAdvice、AfterReturningAdvice
后置通知:AfterReturningAdvice
异常通知:AfterThrowAdvice 有异常才会触发通知内容,没异常就不触发
环绕通知:MethodInterceptor 就是之前和之后都有嘛

spring的AOP就完了,就这么简单,但是:可以玩的东西多得很,接下来就是spring的另一个重点:事务管理

7、spring的事务管理

1)、在玩之前,先来回顾及补充一些spring中和事务相关的东西

  • (1)、isolation 事务隔离级别 ———— 面试必问

    • default 默认,即:采用数据库本身的隔离级别( 建议使用的一种 ),因为:spring中你再怎么整,最后其实还是要听数据库的

    • read-uncommited 读未提交,读取了但是未提交事务嘛,这不就是说的查询吗,但是:很可能发生:脏读 ———— 这种级别适合查询

      • 脏读:就是一个事务读取到了另一个事务还未提交的数据
    • read-commited读提交,就是读取数据并提交了事务嘛,但是:很可能发生:不可重复读 ——— 这种级别适合update,这是oracle数据库的默认级别

      • 不可重复读:就是多个事务去读取表中的同一行数据,但是结果都不一样( update了嘛 )
    • repeatable-read可重复读,多次读取数据嘛,但是:很有可能发生:幻读 ———— 这种级别适合:insert 和 delete,这是mysql的默认级别

      • 幻读:就是多个事务去读取一张表的内容,但是读取到的结果不一样,这种是巧合,如:一个事务读取了一遍,但是另一个事务给表新增了一条数据,而此时又来了一个事务进行读取,这就和第一个事务读取的结果不一样了( 多了一行嘛 )
    • serialized-read可序列化读

事务隔离级别的大小:read-uncommited > read-commited > repeatable-read 》 serialized-read

事务隔离级别的安全性问题:级别越高,越安全,因为:可以读的数据越少了嘛( 约束了咯 )

事务隔离级别的并发性问题:级别越高,当然并发性越低咯,数据都少了,怎么让人多并发嘛

  • 2)、propagation 传播行为

    • 这他喵的指的就是:有新事务进来了,如果前面有事务了怎么处理的问题而已

      • required指的是:如果前面有事务了,当新事务进来时,就和前面的事务合并在一起执行( spring的默认值就是这个 )

      • supports指的是:如果前面有事务了,当新事务进来时,就以非事务的形式来执行

      • 另外的东西:自行面向百度

  • 3)、事务回滚

    • rollback-for

      • 在spring中,如果是RuntimeException异常,则:事务会自动回滚
      • 如果是CheckException( 检查性异常 ),则事务不会回滚,同时会提交事务
        • 想要解决这种checkException的问题:最简单粗暴的一种,直接把抛出的异常弄为Exception;另外一种就是:把checkException上升到RuntimeException就可以了

2)、现在开始玩spring的事务管理

详细见我的spring整合mybatis博客内容:链接如下

spring整合mybatis,附:Spring的事务管理

自此:spring配置版的内容就完毕了,注解版后续弄

第二个基础框架 — spring — xml版,没用注解 — 更新完毕的更多相关文章

  1. 一篇文章带你掌握主流基础框架——Spring

    一篇文章带你掌握主流基础框架--Spring 这篇文章中我们将会介绍Spring的框架以及本体内容,包括核心容器,注解开发,AOP以及事务等内容 那么简单说明一下Spring的必要性: Spring技 ...

  2. Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版)

    Mybatis中使用collection进行多对多双向关联示例(含XML版与注解版) XML版本: 实体类: @Data @NoArgsConstructor public class Course ...

  3. SpringMVC环境搭建---xml版及注解版

    一.建立 JavaWeb 项目(基于Intellij 14.0.3搭建) 1.建立一个 Java 项目,在项目下新建一个文件夹 webapp ,然后在该文件夹下新建一个 WEB-INF 文件夹: 2. ...

  4. Mybatis中使用association及collection进行自关联示例(含XML版与注解版)

    XML版本: 实体类: @Data @ToString @NoArgsConstructor public class Dept { private Integer id; private Strin ...

  5. SSH(Spring Struts2 Hibernate)框架整合(xml版)

    案例描述:使用SSH整合框架实现部门的添加功能 工程: Maven 数据库:Oracle 案例架构: 1.依赖jar包pom.xml <project xmlns="http://ma ...

  6. spring框架-spring.xml配置文件

    运行的时候会报错的,因为写到<bean>标签里面去了,肯定会报错的,要记得把注释删掉,就不会报错了,这样写注释是为了方便下次自己看. <?xml version="1.0& ...

  7. Spring.xml中配置注解context:annotation-config和context:component-scan简述

    XML中context:annotation-config和context:component-scan简述 <context:annotation-config/> 中文意思:<上 ...

  8. Mybatis中使用association及collection进行一对多双向关联示例(含XML版与注解版)

    XML版本: 实体类: package com.sunwii.mybatis.bean; import java.util.ArrayList; import java.util.List; impo ...

  9. web框架 Spring+SpringMvc+Jpa 纯注解搭建

    0.jar包依赖 maven  pom.xml <properties> <spring_version>4.3.25.RELEASE</spring_version&g ...

随机推荐

  1. 密码学基础:AES加密算法

    [原创]密码学基础:AES加密算法-密码应用-看雪论坛-安全社区|安全招聘|bbs.pediy.com 目录 基础部分概述: 第一节:AES算法简介 第二节:AES算法相关数学知识 素域简介 扩展域简 ...

  2. 穿点最多的直线 牛客网 程序员面试金典 C++

    穿点最多的直线 牛客网 程序员面试金典 C++ 题目描述 在二维平面上,有一些点,请找出经过点数最多的那条线. 给定一个点集vectorp和点集的大小n,没有两个点的横坐标相等的情况,请返回一个vec ...

  3. mongoDB 的一般使用

    理解 mongodb 也是nosql 的一种.他的数据存储类型是一种和json格式比较像的数据类型,可以看作就是json. mongodb 里的数据库都是一个单独的库.一般需要用的库都会设置自己的us ...

  4. 创建双向 CA x509 验证证书 kube-apiserver

    1. 设置 kube-apiserver 的 CA 证书相关的文件和启动参数 使用 OpenSSL 工具在 Master 服务器上创建 CA 证书和私钥相关的文件: # openssl genrsa ...

  5. Spark面试题(四)

    1.Spark中的HashShufle的有哪些不足? 1)shuffle产生海量的小文件在磁盘上,此时会产生大量耗时的.低效的IO操作: 2)容易导致内存不够用,由于内存需要保存海量的文件操作句柄和临 ...

  6. httprunner3源码解读(4)parser.py

    源码结构目录 可以看到此模块定义了4个属性和12个函数,我们依次来讲解 属性源码分析 # 匹配http://或https:// absolute_http_url_regexp = re.compil ...

  7. Qt 窗口阴影效果的实现

    前言 今天正好搞一下窗口的阴影,发现一篇文章写的真是不错.毫不犹豫滴转过来了,感谢作者分享. 转自:http://blog.sina.com.cn/s/blog_a6fb6cc90101eoop.ht ...

  8. Cannot load module file xxx.iml的两种解决方法

    一. 一种是点击左上角File,然后点击Invalidate Caches / Restart...,弹出对话框再点击Invalidate and Restart等待工程重新加载,问题就解决了. 二. ...

  9. 多层pcb线路板的制作流程

    PCB制作第一步是整理并检查pcb多层线路板布局(Layout).电路板制作工厂收到PCB设计公司的CAD文件,由于每个CAD软件都有自己独特的文件格式,所以深圳PCB板厂会转化为一个统一的格式Ger ...

  10. 大一C语言学习笔记(5)---函数篇-定义函数需要了解注意的地方;定义函数的易错点;详细说明函数的每个组合部分的功能及注意事项

    博主学习C语言是通过B站上的<郝斌C语言自学教程>,对于C语言初学者来说,我认为郝斌真的是在全网C语言学习课程中讲的最全面,到位的一个,这个不是真不是博主我吹他哈,大家可以去B站去看看,C ...