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. 电脑cmd命令快速查看连接过的WIFI密码信息

    只是突然发现,好奇心作怪,试了一下,妈妈再也不用担心我忘记家里的wifi密码了 1.直接打开"运行"(win键+R) 2.输入CMD 确定 3.输入下面cmd命令.鼠标粘贴 for ...

  2. 基于live555开发嵌入式linux系统的rtsp直播服务

    最近要搞一个直播服务,车机本身是个前后双路的Dvr,前路1080P 25fps,后路720P 50fps,现在要连接手机app预览实时画面,且支持前后摄像头画面切换. 如果要做直播,这个分辨率和帧率是 ...

  3. 理解ASP.NET Core - 文件服务器(File Server)

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 提供静态文件 静态文件默认存放在 Web根目录(Web Root) 中,路径为 项目根目录(C ...

  4. Linux cat文件正常,vim文件乱码

    cat: vim: 1.临时解决 vim 文件后,命令模式下执行: :set encoding=utf-8 2.永久解决 vi    配置文件路径:/etc/virc vim 配置文件路径:/etc/ ...

  5. storm调用kafka重复消费的问题

    1. 实现IBolt接口的bolt需要显式调用collector.ack(); 2. 继承自BaseBasicBlot的bolt, 会帮你自动调用ack的

  6. LiteFlow 2.6.4版本发行注记,里程碑版本!

    一 这个版本做的很折腾.期间几个issue推翻重做了好几次. 但我最终还是带来了LiteFlow 2.6.4这个重要版本. 虽然版本是小版本号升级,但是带来的更新可一点也不少.并完全向下兼容. 如果你 ...

  7. 大爽Python入门教程 3-4 实践例题

    大爽Python入门公开课教案 点击查看教程总目录 1. 求和 使用循环,计算列表所有项的和,并输出这个和. 列表示例 lst = [8, 5, 7, 12, 19, 21, 10, 3, 2, 11 ...

  8. 【ASP.NET Core】体验一下 Mini Web API

    在上一篇水文中,老周给大伙伴们简单演示了通过 Socket 编程的方式控制 MPD (在树莓派上).按照计划,老周还想给大伙伴们演示一下使用 Web API 来封装对 MPD 控制.思路很 Easy, ...

  9. Pycharm下载安装详细教程

    目录 1.Pycharm 简介 2.Pycharm下载 3.环境变量的配置 4.Pycharm的使用 1.Pycharm 简介 PyCharm是一种Python IDE(Integrated Deve ...

  10. win10开机自启

    所有用户的开机自启文件夹 英文路径 # ProgramData目录是隐藏的 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp 中 ...