Spring框架

Spring框架

一、Spring框架的发展历史

  • Spring:春天–>Spring这个框架给软件行业带来了春天
  • 2002年,首次推出了Spring框架的雏形:interface21框架
  • Spring框架既以interface21框架为基础,经过重新设计,并不断丰富其内涵,在2004.3.24,发布了1.0正式版
  • Rod Jhonson,Spring Frameword创始人,著名作者,他的专业不是计算机,而是音乐学
  • Springl理念:使现有的技术更加容易使用,Spring本身是一个大杂烩,整合了现有的技术框架!

 
 

二、市面上比较流行的架构方式

  • SSH:Struct2+Spring+Hibernate! (现在基本上过时了)
  • SSM:Spring+SpringMVC+Mybatis!

 
 

三、说了这么多,那到底什么是Spring,Spring 解决了什么问题,为什么要使用 Spring?

Spring 是个Java企业级应用的开源框架。它主要用来开发Java应用。Spring 框架目标是简化企业项目开发,它的理念是使现有的技术更容易使用,Spring本身是一个大杂烩,整合了现有的技术框架。
主要有以下几个模块组成:(这里先简单写一下,下面会详细写)
Spring Core:Spring核心类库,提供IOC服务的。
Spring Context:提供框架式的Bean访问方式,以及企业级能力(JNDI、定时任务等)
Spring AOP:AOP服务
Spring DAO:对JDBC的抽象,简化了数据访问异常的处理
Spring ORM:对现有的ORM框架的支持
Spring Web:提供了面向Web的综合特性,例如多方文件上传
Spring MVC:提供面向Web应用的Model-View-Controller实现
 
 
Spring 解决了什么问题?我们为什么要使用 Spring 框架?

  我们平常在使用 SpringMVC,SpringBoot 做实际开发的时候,我们的pojo类,Dao层和Service层和Conntroller层中,所有的类我们都没有去手动的初始化过,我们知道 Java 语言是面向对象的,但是我们都没都创建过对象何来面向对象呢,所以,这些事情 Spring 都帮我们做好了。

  大家都知道 Spring 本身就是个大容器,他里面存的是什么呢,就是存储的一个个的已经初始化好的对象(懒加载暂时不提),Spring 在运行的时候,会去加载我们的配置文件(Springboot就是加载启动类开始),然后根据你配置好的路径去加载指定的类或者让指定的注解生效,意思就是创建Bean,然后把这些类统统的初始化一遍。之后才会有我们通常所说的依赖注入,依赖注入就是把 Spring 已经初始化好的对象注入指定的对象中,但是它在这么多对象中是怎么找到和它自己匹配的对象呢,我们这里只说注解的方式依赖注入。

@Autowired是Spring框架提供的一个依赖注入的注解,它主要是根据byType的方式来进行依赖注入的,如果需要根据byName来进行依赖注入,需要和@Quilifier注解来配合使用。

总结:Spring 这个框架帮我们解决了对象初始化的问题,我们不需要去手动初始化一个一个的类,Spring都会帮我们自动初始化,需要用的时候自己去拿就行了。

 
 

四、Spring的官网和项目引入

Spring官网: Spring | Learn
官方下载地址: Index of release/org/springframework/spring
Github:spring-projects/spring-framework: Spring Framework (github.com)
Maven依赖:

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.8</version>
</dependency>

 
 

五、Spring框架的优点

我们在项目中为什么要使用Spring框架?

  1. Spring是一个开源的免费的框架(容器)。
  2. Spring是一个轻量级的(本身很小,下载一个包就可以用了)、非入侵式的框架(引入了Spring不会改变你原来的代码情况)!基本的版本大约是2MB,如果是入侵式的就是你导入了一个jar包导致你原来的项目不能用了。
  3. 控制反转(IOC):Spring通过控制反转实现了松散耦合
  4. 和面向切面编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
  5. 容器:Spring 包含并管理应用中对象的生命周期和配置。
  6. MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
  7. 支持事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
    8.Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。

总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!
 
 

六、Spring框架的缺点

1.发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱”。
 
 

七、Spring框架的组成结构

请添加图片描述

  1. 核心容器SpringCode: 核心容器提供Spring框架的基本功能。—-它主要的组件就是BeanFactory,是工厂模式的实现。同时BeanFactory适用控制反转(IOC)思想将应用程序的配置和依赖性规范与实际的应用程序分开。

  2. Spring Context: Spring上下文是一个配置文件,主要向框架提供上下文信息。

  3. SpringAop: 通过配置管理特性,SpringAOP模块直接将面向切面地编程功能集成到了Spring框架中,所以,它可以很容易地使Spring框架管理的任何对象支持AOP。SpringAOP模块也是基于Spring的应用程序中的对象提供了事务管理服务。—–比较强大的功能。

  4. SpringDAO: 它主要和dao层相关联,可以用该结构来管理异常处理和不同数据库供应商抛出的错误信息。其中异常层次结构简化了错误处理,并且极大地降低了需要编写地异常代码数据(例如打开和关闭连接)。

  5. Spring ORM : Spring框架中插入了若干个ORM框架,从而提供了ORM的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

  6. SpringWEB模块: Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

  7. SpringMVC:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、FreeMarker、Velocity、Tiles(jsp布局)、iText(报表处理) 和 poi。

 
 

八、SpringIOC

1、IOC理论的推导

1.UserDao 接口
2.UserDAOImpl实现类
3.UserService业务接口
4.UserServiceImpl业务实现类

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求请修改源代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!

我们使用了一个Set接口实现,已经发生了革命性的变化!

private UserDAO userDao;

//利用set进行动态实现值的注入

public void setUserDao(UserDao userDao)  {
this.userDao = userDao;
}
  • 之前,程序是主动创建对象,控制权在程序员手上!
  • 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象!

让程序通过某种方式被动得接受对象的操作:这就叫控制反转。

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了,系统的耦合性大大减低,可以更加专注的在业务的实现上!这时IOC的原型!请添加图片描述
请添加图片描述
请添加图片描述

2、 那说白了,什么是SpringIOC?

我们由一个图来解释什么是SpringIOC。请添加图片描述
控制反转是一种通过(XML或者是注解)并通过第三方去生产获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入。

根据上述的这句话,我自己手撸了一个微型版的SpringIOC 和 AOP 具体见:
博客:
GitHub:

对于控制反转,在熟记上述的概念之后,我们还要会对控制反转进行拆分,分别为 控制 和 反转
控制:谁来控制对象的创建,传统的应用程序的对象是由我们手动new出来的,在我们使用Spring之后,对象是由Spring来创建的。
反转:程序本身不创建对象,而变成被动的接收对象。
那什么又是依赖注入呢?
所谓的依赖注入就是利用set()方法进行注入。
总结来说:所谓的IOC,就一句话:对象由Spring来创建,管理和装配。

3、SpringIOC的几种注入方式

1、构造器注入

使用构造器注入对象的方式,我们默认使用的是无参构造创建对象!
如果我们要使用有参构造创建对象,有以下三种方式

第一种方式:下标法
<constructor-arg index= "0" value = "zhangsan"></constructor>
第二种方式:通过类型创建
<constructor-arg type= "java.lang.String" value = "zhangsan"></constructor>

注意:这个不推荐使用,因为如果有两个相同类型的好像就无法识别了

第三种方式:直接通过参数名来创建,我们一般都用这个
<constructor-arg name= "name" value = "zhangsan"></constructor>

我们之后写每一个类都要把它注册到beans.xml Spring的配置文件中,要养成好习惯!!!
在bean.xml中的所有bean,一旦被注册到配置文件中,我们启动项目的时候,就被Spring底层通过Java的反射机制动态注入,所以可以直接拿过来使用。
总结:Spring通过构造器创建对象的方式一共有四种,无参的一种,有参的三种,一般我们会使用参数名的方式来创建,在配置文件被加载的时候,Spring容器中的对象就已经被初始化了!Spring容器,指的是配置文件中的beans!

2、依赖注入

依赖注入,之前说了说白了底层就是利用set()进行注入,我将其拆开来。
依赖:bean对象的创建依赖于容器。
注入:bean对象中的所有属性,由容器来注入
依赖注入共有8种注入
第一种:普通注入,name:value
第二种,引用注入,name:ref
第三种,数组注入

<property name = "">
	<array>
		<value></value>
		<value></value>
		<value></value>
	</array>
</property>

第四种,List集合注入

<property name = "">
	<list>
		<value></value>
		<value></value>
		<value></value>
	</list>
</property>

第五种,Set集合注入

<property name = "">
	<set>
		<value></value>
		<value></value>
		<value></value>
	</set>
</property>

第六种,map集合注入

<property name = "">
	<map>
	  <entry key="" value=""></value>
	  <entry key="" value=""></value>
	  <entry key="" value=""></value>
	</map>
</property>

第七种,null注入

<property name = "">
	<null/>
</property>

第八种,Properties注入

<property name = "">
	<props>
	  <prop key="" >value</value>
	  <prop key="" >value</value>
	  <prop key="" >value</value>
	</props>
</property>
3、 P命名空间和C命名空间注入

P命名空间注入:
在beans标签后面加上如下第三方地址:

xmlns:p="http://www.springframework.org/schema/p"

C命名空间注入:
在beans标签后面加上如下第三方地址:

xmlns:c="http://www.springframework.org/schema/c"

 

总结:SpringIOC

在说Spring IOC之前,我们还要来讲讲历史,我们先来看在 Spring 没有出现之前我们是怎么样创建新的对象的,在没有 Spring 之前,我们一般都是使用new操作符来创建对象的,这一个过程需要我们程序员手动去声明,而 Spring 出现之后,我们程序员将这个手动创建对象这个过程交给spring容器去做。

那么具体什么是IOC控制反转呢?所谓控制反转,是指一种通过(XML或者是注解)并通过第三方组件去生产和获取特定对象的方式。我们可以把控制反转拆开来,控制:谁来控制对象的创建,传统的应用程序的对象是由我们手动new出来的,在我们使用Spring之后,对象是由Spring来创建的。反转:程序本身不创建对象,而变成被动的接收对象。我们将本来我们需要手动去创建对象这一个过程全程交给spring容器去,由spring负责对象的创建,管理和装配。spring IOC,底层通过Java的反射 机制和 动态代理模式来实现的。在讲到spring IOC的注入之前,我们先来看看其最基本的依赖注入,我们在类中声明一个对象,我们一般如何初始化这个类,我们会使用set()方法进行初始化,也就是注入。依赖注入,什么是依赖注入呢?依赖注入就是,我们依赖spring这个容器,底层通过Java的反射机制和动态代理模式通过set()方法对一个对象进行初始化的过程。Spring的IOC有三种依赖注入方式分别是, :构造器注入、setter方法注入、根据注解注入。总结来说:所谓的IOC,就一句话:对象由Spring来创建,管理和装配。
 

九、关于Spring中的Bean?

1、Spring支持几种作用域(Scope)的bean?

Spring容器中的bean可以分为5个范围:
1、singleton(单例模式):每次从容器中getBean的时候,都只会拿之前创建好的哪一个对象,这是Spring默认的机制。
注意:单线程一般都使用singleton

<bean id="address" class="com.at.cheng.pojo.Address" scope="singleton">
    <property name="address" value="广东"></property>
</bean>

请添加图片描述

2、prototype(原型模式):每次从容器中get的时候,都会产生一个新的对象
注意:多线程可以使用prototype

<bean id="address" class="com.at.cheng.pojo.Address" scope="prototype">
    <property name="address" value="广东"></property>
</bean>

请添加图片描述
其余的作用域,我们只能在web开发中使用。
3、request:为每一个网络请求创建一个实力,在请求完成之后,bean会失效并被垃圾回收器回收。
4、session:与request类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
5、global-session:全局作用域,global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那 么这全局变量需要存储在global-session中。全局作用域与Servlet中的session作用域效果相同。

2、Spring框架中的单例Bean是线程安全的么?

Spring框架并没有对单例Bean进行任何多线程的封装处理。
关于单例Bean的线程安全和并发问题,需要开发者自行去搞定。
单例的线程安全问题,并不是Spring应该去关心的,Spring应该做的是,根据提供的配置创建单例Bean或多例Bean的功能。
当然,实际上,大部分的SpringBean并没有可变的状态,所以在某种程度上说 Spring 的单例
Bean 是线程安全的。如果你的 Bean 有多种状态的话,就需要自行保证线程安全。最浅显的解决办法,就是将多态 Bean 的作用域(Scope)由 Singleton 变更为 Prototype。

3、说一说Spring Bean的生命周期

Spring Bean的生命周期是一个比较复杂的过程,具体详细见我另一篇博客:Spring Bean 的生命周期

 
 

十、SpringAOP

1、SpringAOP的切入点

我们在开发代码的时候通常是纵向开发:dao——service——controller——再到前端,我们这个流程在之前已经完成了,但是我们想给我们我们之前写的代码加入日志log的功能,我又得去修改我原有的代码,在修改的过程中,我可能会写出bug,从而导致我先前写的代码全盘奔溃。这样就违背了我们OOP面向对象的开闭原则,对拓展开放,对修改关闭。

就在这个时候,我们为了不改变纵向开发的代码,防止纵向开发的代码全盘奔溃,我们就需要用代理模式来实现横向插入到纵向开发,而这也是AOP的实现机制,面向切面编程。

请添加图片描述

2、什么是AOP?

SpringAOP总结成一句话就是:AOP是一个横向的面向切面编程的思想,指在不影响原来业务的情况下,实现动态的增强。

Spring AOP是基于动态代理的,如果要代理的对象实现了某个接口,那么Spring AOP就会使用JDK动态代理去创建代理对象(房东要租房,房东实现租房这个接口,Spring AOP就会使用JDK动态代理生成租房代理对象,既中介);而对于没有实现接口的对象,就无法使用JDK动态代理,转而使用CGlib动态代理生成一个被代理对象的子类来作为代理(生成房东的子类来作为代理)。

当然也可以使用AspectJ,Spring AOP中已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。使用AOP之后我们可以把一些通用功能抽象出来,在需要用到的地方直接使 用即可,这样可以大大简化代码量。我们需要增加新功能也方便,提高了系统的扩展性。
只要你提到了AspectJ,那么我就应该准备说一说AspectJ了

3、Spring AOP和AspectJ AOP有什么区别?

1、SpringAOP属于运行时增强,而AspectJ是编译时增强的。
2、SpringAOP是基于代理的,而AspectJ是基于字节码操作的。
3、如果我们的切面比较少,那么两者性能差异不大,但是如果切面太多的话,最好选择AspectJ,它比SpringAOP快很多。

Spring AOP已经集成了AspectJ,AspectJ应该算得上是Java生态系统中最完整的AOP框架了。
AspectJ相比于Spring AOP功能更加强大,但是Spring AOP相对来说更简单。

说到切面问题,那么我就应该准备说一说,关注点和横切关注点的区别了

4、在SpringAOP中,关注点和横切关注点的区别是什么?

关注点:关注点在是应用中的一个模块的行为,一个关注点可能会被定义成为我们想要去实现的一个功能。
横切关注点:横切关注点是一个关注点,这个关注点是整个应用都会用到的功能,并影响整个应用,比如日志、安全等等,几乎应用的每个模块都需要的功能。
连接点:连接点代表着一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是应用程序执行SpringAOP的位置。
切入点:切入点是一个或者是一组连接点,通知将在这些位置上执行。

5、切面通知又是什么,它有哪些类型呢?

切面通知是在方法执行前或者是方法执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码。

Spring的切面(通知)可以分为五种类型的通知:
1、before:方法执行前被调用。
2、after:无论方法是否执行成功,方法执行后都会被调用。
3、after-returing:仅当方法执行成功后才会被调用。
4、after-throwing:在方法抛出异常退出时才会被调用的通知。
5、around:在方法执行之前和之后调用的通知。

5、使用AOP的场景

AOP常用的场景有以下几个:
1、为代码添加日志功能
2、JDBC事务管理
3、权限管理

 
 

十一、关于Spring框架中的事务

关于事务的知识点和Spring框架中的事务具体见我另一篇博客:Java事务

 
 

十一、Spring 和 SpringBoot 的区别

有关Spring 和 SpringBoot 的区别见我其他博客:Spring 和 SpringBoot 的区别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值