详谈Spring定义

Posted lyq666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详谈Spring定义相关的知识,希望对你有一定的参考价值。

什么是Spring?
答:Spring是分层的JavaEE/SE轻量级开源框架,以IOC和AOP为内核,使用基本的JavaBean来完成以前可以用RJB完成的工作。

在实际开发中,通常服务器端采用三层体系结构,表示层(Web),业务逻辑层(Service),持久层(Dao)。Spring对每一层都提供了技术支持。
表示层:在表示层提供了与struts等框架的整合
业务逻辑层:在业务逻辑层可以管理实务,记录日志等
持久层:在持久层可以整合Hibernate、JdbcTemplate等技术。

Spring框架的优点:
1.非侵入式设计
2.方便解耦,简便开发
3.支持AOP
4.支持声明式事务处理
5.方便程序测试
6.方便集成各种优秀框架
7.降低JavaEE API使用难度

Spring 的体系结构(简化版)
1.Core Container(核心容器)
Beans:提供BeanFactory,Spring 将管理对象称为Bean
Core:提供了Spring框架的基本组成部分,包括IOC和DI功能
Context:建立在Beans和Core模块基础上,他是访问定义和配置任何对象的媒介
2.Data Access/Intergration(数据访问/集成)
JDBC:提供一个JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码
ROM:对流性对象关系的映射API,包括JPA,JDO和Hibernate提供了集成层支持
3.Web
Servlet:也称Spring-webmvc模块,包含Spring模型-视图-控制器(MVC)和RESR Web Services实现的web程序
Web:提供了基本的web开发集成特性,如:多文件上传、使用Servlet监听器来初始化IOC容器及web应用上下文
4.其他模块:
AOP:面向切面编程实现,允许方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
.....

String开发所需要的jar包需要两部分:Spring 框架包和第三方依赖包
Spring框架包:下载地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/4.3.6.RELEASE/
解压后目录如下:
docs文件夹中包含API文档和开发规范
libs文件夹中包含JAR包和源码
Schema文件夹中包含开发所需要的schema文件
以.RELEASE.jar结尾的是class文件JAR包
以.RELEASE-javadoc.jar结尾的是API文档压缩包
以.RELEASE-sources.jar结尾的是源文件压缩包
在libs 目录下有四个Spring基础包,分别对应Spring核心容器的四个模块
spring-core-4.3.6.RELEASE.jar
包含Spring框架的核心工具类,Spring其它组件都要用到这个包里的类。
spring-beans-4.3.6.RELEASE.jar
所有应用都要用到的JAR包,它包含访问配置文件、创建和管理Bean以及进行控制反转或者依赖注入操作相关的所有类。
spring-context-4.3.6.RELEASE.jar
提供了在基础IoC功能上的扩展服务,还提供了许多企业级服务的支持
spring-expression-4.3.6.RELEASE.jar
定义了Spring的表达式语言。
第三方依赖包:在使用Spring开发时,除了要使用自带的JAR包外,Spring的核心容器还需要依赖commons.logging的JAR包。
下载地址:http://commons.apache.org/proper/commons-logging/download_logging.cgi

Spring的核心容器:Spring容器会负责程序之间的关系,而不是由程序代码直接控制。Spring为我们提供了两种核心容器,BeanFactory和ApplicationContest。
创建BeanFactory实例时,需要提供Spring所管理容器的详细配置信息,这些信息通常采用XML文件形式来管理,其加载配置信息的语法如下:
BeanFactory beanFactory =
new XmlBeanFactory(new FileSystemResource("F: /applicationContext.xml"));
XML配置文件的位置
ApplicationContest是BeanFactory的子接口,是另一种Spring核心容器它由org.springframework.context.ApplicationContext接口定义,
不仅包含了BeanFactory的所有功能,还添加了对国际化、资源访问、事件传播等方面的支持。创建ApplicationContext接口实例,通常采用两种方法,具体如下:

通过ClassPathXmlApplicationContext创建 :
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(String configLocation);
ClassPathXmlApplicationContext会从类路径classPath中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。

通过FileSystemXmlApplicationContext创建 :
ApplicationContext applicationContext =
new FileSystemXmlApplicationContext(String configLocation);
FileSystemXmlApplicationContext会从指定的文件系统路径(绝对路径)中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。

在Java项目中,会通过ClassPathXmlApplicationContext类来实例化ApplicationContext容器。
而在Web项目中,ApplicationContext容器的实例化工作会交由Web服务器来完成。
Web服务器实例化ApplicationContext容器时,通常会使用ContextLoaderListener来实现,此种方式只需要在web.xml中添加如下代码:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:spring/applicationContext.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

创建Spring容器后,就可以获得Spring 容器中的Bean。Spring获取Bean通常采取两种方法:
Object getBean(String name);
根据容器中的ID或者name来获取指定的Bean,获取之后要进行强制转换
<T>T getBean (Class <T>requiredType);
根据类的类型来获取Bean,因为是泛型,所以不用强制转换

Spring的入门程序看PPT(1)

DI的全称是Dependency Injection,中文称之为依赖注入。它与控制反转(IoC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。
IOC:
在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,
而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到了Spring容器,控制权发生了反转,这就是控制反转。
DI:
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。

什么是Spring中的Bean?
如果把Spring看做一个大型工厂,则Spring容器中的Bean就是该工厂的产品。要想使用这个工厂生产和管理Bean,就需要在配置文件中告诉它需要哪些Bean,
以及需要使用何种方式将这些Bean装配到一起。
Bean的本质就是Java中的类,而Spring中的Bean其实就是对实体类的引用,来生产Java类对象,从而实现生产和管理Bean 。

在实际开发中,最常使用的是XML文件格式的配置方式,这种配置方式是通过XML文件来注册并管理Bean之间的依赖关系。
XML配置文件的根元素是<beans>,<beans>中包含了多个<bean>子元素,每一个<bean>子元素定义了一个Bean,并描述了该Bean如何被装配到Spring容器中。
关于<beans>元素的常用属性如下表所示:
属性或者子元素名称 描述
id 是一个bean的唯一标识符,spring容器对bean的配置、管理都通过该属性来完成

name spring容器同样可以通过此属性对容器的Bean进行配置和管理,name属性可以为bean指定多个名称,
每个名称用逗号或分号隔开。
class 该属性指定了Bean的具体实现类,他必须是一个完整的类名,实用类的全限名称

scope 用来设定Bean实例的作用域,其属性值有,singleton(单例)、prototype(原型)、
request、session、global Session、application和websocket。其默认值为singleton

在配置文件中,通常一个普通的Bean只需要定义id(或name)和class 两个属性即可,定义Bean的方式如下所示:
<?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">
<bean id="bean1" class="com.itheima.Bean1" />
<bean name="bean2" class="com.itheima.Bean2" />
</beans>
如果在Bean中未指定id和name,则Spring会将class值当作id使用。

Bean的实例化有哪些方式?
在面向对象的程序中,想要使用某个对象,就需要先实例化这个对象。同样,在Spring中,要想使用容器中的Bean,也需要实例化Bean。
实例化Bean有三种方式,分别为
构造器实例化、静态工厂方式实例化和实例工厂方式实例化(其中最常用的是构造器实例化)。

Spring 4.3中为Bean的实例定义了7种作用域,如下表所示:PPT2.3.1
在上表7种作用域中,singleton和prototype是最常用的两种作用域。
singleton是Spring容器默认的作用域,当Bean的作用域为singleton时,Spring容器就只会存在一个共享的Bean实例。
singleton作用域对于无会话状态的Bean(如Dao 组件、Service组件)来说,是最理想的选择。
在Spring中如何配置prototype作用域?
在Spring配置文件中,同样使用<bean>元素的scope属性,将Bean的作用域定义成prototype 。
<bean id="scope" class="com.itheima.scope.Scope" scope=" prototype "/>

Spring容器可以管理Bean部分作用域的生命周期。有关说明具体如下:
singleton 作用域:Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化完成,以及何时被销毁。
prototype作用域:prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。

什么是Bean的装配?
Bean的装配可以理解为依赖关系注入,Bean的装配方式即Bean依赖注入的方式。Spring容器支持多种形式的Bean的装配方式,
如基于XML的装配、基于注解(Annotation)的装配和自动装配(其中最常用的是基于注解的装配),本节将主要讲解这三种装配方式的使用。

Annotation使用方式如下:
创建接口UserDao,定义方法
创建接口实现类UserDaoImpl用@Repository声明类
创建接口UserService,并定义方法
创建接口实现类UserDaoImpl,用@Repository声明类;
创建接口UserService,并定义方法;
创建控制器类,用@Controller声明,并使用@Resource注入UserService属性;
创建Spring配置文件,配置Bean;
创建测试类,测试程序
除了可以像示例中通过<bean>元素来配置Bean外,还可以通过包扫描的形式来配置一个包下的所有Bean:
<context:component-scan base-package="com.itheima.annotation" />

本章对Spring的Bean进行了详细讲解,首先介绍了Bean的配置,然后通过案例讲解了Bean实例化的三种方式,接下来介绍了Bean的作用域和生命周期,最后讲解了Bean的三种装配方式。
通过本章的学习,要求读者了解Bean的装配过程,并能使用Bean的装配进行开发。


第三章
AOP详解:
AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP核心概念
1、横切关注点

对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

2、切面(aspect)

类是对物体特征的抽象,切面就是对横切关注点的抽象

3、连接点(joinpoint)

被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

4、切入点(pointcut)

对连接点进行拦截的定义

5、通知(advice)

所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

6、目标对象

代理的目标对象

7、织入(weave)

将切面应用到目标对象并导致代理对象创建的过程

8、引入(introduction)

在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

Spring对AOP的支持
Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了

2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

什么是AOP?
AOP的全称是Aspect-Oriented Programming,即面向切面编程(也称面向方面编程)。
它是面向对象编程(OOP)的一种补充,目前已成为一种比较成熟的编程方式。
Spring中的两种动态代理:JDK动态代理、CGLIB代理
JDK动态代理:
JDK动态代理是通过java.lang.reflect.Proxy类来实现,我们可以调用proxy类的newProxyInstance()方法来创建代理对象。
对于使用业务接口的类,Spring会默认使用JDK动态代理来实现AOP。
通过前面的学习可知,JDK的动态代理用起来非常简单,但它是有局限性的,使用动态代理的对象必须实现一个或多个接口。
那么,如何代理没有实现接口的类?
如果想代理没有实现接口的类,那么可以使用CGLIB代理。
CGLIB(Code Generation Library)是一个高性能开源的代码生成包,它采用非常底层的字节码技术,对指定的目标类生成一个子类,并对子类进行增强。
CGLIB(Code Generation Library)是一个开源项目!是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。

Spring按照通知在目标类方法的连接点位置,可以分为5种通知类型,具体如下:
MethodBeforeAdvice(前置通知)
AfterReturningAdvice(后置通知)
MethodInterceptor(环绕通知)
异常通知
(ThrowsAdvice)引入通知
org.springframework.aop.MethodBeforeAdvice(前置通知)
在目标方法执行前实施增强,可以应用于权限管理等功能。
org.springframework.aop.AfterReturningAdvice(后置通知)
在目标方法执行后实施增强,可以应用于关闭流、上传文件、删除临时文件等功能。
org.aopalliance.intercept.MethodInterceptor(环绕通知)
在目标方法执行前后实施增强,可以应用于日志、事务管理等功能。
org.springframework.aop.ThrowsAdvice(异常抛出通知)
在方法抛出异常后实施增强,可以应用于处理异常记录日志等功能。
org.springframework.aop.IntroductionInterceptor(引介通知)
在目标类中添加一些新的方法和属性,可以应用于修改老版本程序。

ProxyFactoryBean是FactoryBean接口的实现类,FactoryBean负责实例化一个Bean,而ProxyFactoryBean负责为其他Bean创建代理实例。
在Spring中,使用ProxyFactoryBean是创建AOP代理的基本方式。

AspectJ开发
AspectJ是一个基于Java语言的AOP框架,它提供了强大的AOP功能。Spring 2.0以后,Spring AOP引入了对AspectJ的支持,并允许直接使用AspectJ进行编程,
而Spring自身的AOP API也尽量与AspectJ保持一致。新版本的Spring框架,也建议使用AspectJ来开发AOP。
使用AspectJ实现AOP有两种方式:一种是基于XML的声明式AspectJ,另一种是基于注解的声明式AspectJ。

1.配置切面
在Spring的配置文件中,配置切面使用的是<aop:aspect>元素,该元素会将一个已定义好的Spring Bean转换成切面Bean,所以要在配置文件中先定义一个普通的Spring Bean。
配置<aop:aspect>元素时,通常会指定id和ref两个属性
2.配置切入点
当<aop:pointcut>元素作为<aop:config>元素的子元素定义时,表示该切入点是全局切入点,它可被多个切面所共享;
当<aop:pointcut>元素作为<aop:aspect>元素的子元素时,表示该切入点只对当前切面有效。
在定义<aop:pointcut>元素时,通常会指定id和expression两个属性
3.配置通知
使用<aop:aspect>的子元素可以配置5种常用通知,这5个子元素不支持使用子元素,但在使用时可以指定一些属性,其常用属性及其描述如下:

基于注解的声明式AspectJ
spectJ框架为AOP的实现提供了一套注解,用以取代Spring配置文件中为实现AOP功能所配置的臃肿代码。AspectJ的注解及其描述如下所示:


第四章

Spring JDBC模块有什么作用?
Spring的JDBC模块负责数据库资源管理和错误处理,大大简化了开发人员对数据库的操作,
使得开发人员可以从繁琐的数据库操作中解脱出来,从而将更多的精力投入到编写业务逻辑当中。

针对数据库的操作,Spring框架提供了JdbcTemplate类,该类是Spring框架数据抽象层的基础。可以说,JdbcTemplate类是Spring JDBC的核心类。
核心类JdbcTemplate --- extends JdbcAccessor
--- implements JdbcOperations
从JdbcTemplate的继承关系图可以看出,JdbcTemplate类的直接父类是JdbcAccessor,该类为子类提供了一些访问数据库时使用的公共属性。
DataSource:其主要功能是获取数据库连接,还可以引入对数据库连接的缓冲池和分布式事务的支持,它可以作为访问数据库资源的标准接口。
SQLExceptionTranslator:该接口负责对SQLException进行转译工作。通过必要的设置获取SQLExceptionTranslator中的方法,
可以使JdbcTemplate在需要处理SQLException时,委托SQLExceptionTranslator的实现类来完成相关的转译工作。
而JdbcOperations接口定义了在JdbcTemplate类中可以使用的操作集合,包括添加、修改、查询和删除等操作。

Spring JDBC的配置
Spring JDBC模块主要由4个包组成,分别是core(核心包)、dataSource(数据源包)、object(对象包)和support(支持包)。

从上表可以看出,Spring对数据库的操作都封装在了这几个包中,而想要使用Spring JDBC,就需要对其进行配置。
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="xxx" class="Xxx">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
关于上述示例dataSource配置中的4个属性说明,如下表所示:
driverClassName:所使用的驱动名称,对应驱动jar包中的Driver类
url:数据源所在地址
username:访问数据库的用户名
password:访问数据库的密码

Spring JdbcTemplate的常用方法
在JdbcTemplate核心类中,提供了大量的更新和查询数据库的方法,我们就是使用的这些方法来操作数据库的。
execute()
execute(String sql)方法可用于执行sql语句
update()
update()用于执行插入、更新和删除操作
query()
query()用于执行数据查询操作


第五章
事物
理解事务之前,先讲一个你日常生活中最常干的事:取钱。
比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱;然后ATM出1000元钱。这两个步骤必须是要么都执行要么都不执行。如果银行卡扣除了1000块但是ATM出钱失败的话,你将会损失1000元;如果银行卡扣钱失败但是ATM却出了1000块,那么银行将损失1000元。所以,如果一个步骤成功另一个步骤失败对双方都不是好事,如果不管哪一个步骤失败了以后,整个取钱过程都能回滚,也就是完全取消所有操作的话,这对双方都是极好的。
事务就是用来解决类似问题的。事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。
在企业级应用程序开发中,事务管理必不可少的技术,用来确保数据的完整性和一致性。
事务有四个特性:ACID
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。

什么是Spring的事务管理?
在实际开发中,操作数据库时都会涉及到事务管理问题,为此Spring提供了专门用于事务处理的API。
Spring的事务管理简化了传统的事务管理流程,并且在一定程度上减少了开发者的工作量。
在Spring的所有JAR包中,包含一个名为spring-tx-4.3.6.RELEASE的JAR包,该包就是Spring提供的用于事务管理的依赖包。
在该JAR包的org.springframework.transaction包中,有3个接口文件PlatformTransactionManager、
TransactionDefinition和
TransactionStatus,如下图所示:
PlatformTransactionManager接口是Spring提供的平台事务管理器,主要用于管理事务。该接口中提供了三个事务操作的方法,具体如下:
TransactionDefinition接口是事务定义(描述)的对象,该对象中定义了事务规则,并提供了获取事务相关信息的方法,具体如下:
上述方法中,事务的传播行为是指在同一个方法中,不同操作前后所使用的事务。传播行为有很多种。
TransactionStatus接口是事务的状态,它描述了某一时间点上事务的状态信息。该接口中包含6个方法,具体如下:

Spring事务管理分两种方式:
编程式事务管理:通过编写代码实现的事务管理,包括定义事务的开始、正常执行后的事务提交和异常时的事务回滚
声明式事务管理:通过AOP技术实现的事务管理,主要思想是将事务作为一个“切面”代码单独编写,然后通过AOP技术将事务管理的“切面”植入到业务目标类中
声明式事务管理最大的优点在于开发者无需通过编程的方式来管理事务,只需在配置文件中进行相关的事务规则声明,就可以将事务应用到业务逻辑中。
这使得开发人员可以更加专注于核心业务逻辑代码的编写,在一定程度上减少了工作量,提高了开发效率,所以在实际开发中,通常都推荐使用声明式事务管理。
如何实现Spring的声明式事务管理?
Spring的声明式事务管理可以通过两种方式来实现,一种是基于XML的方式,另一种是基于Annotation的方式。

 

 

 

 

 









以上是关于详谈Spring定义的主要内容,如果未能解决你的问题,请参考以下文章

详谈设计-单例模式全网最详解读

分分钟搞定Spring5轻轻松松一遍过

详谈设计模式——全网最详细的设计模式系列

C++_继承详谈

C++_继承详谈

C++_多态详谈