Java之Spring知识点

Posted

tags:

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

1.AOP的概念是Aspected Oriented Programming 面向方面编程。

好处:AOP将程序分解成各个方面或者说关注点。这使得可以模块化,相当横向上分切了。它可以解决OOP和过程化方法不能够很好解决的横切(crosscut)问题,如:事务、安全、日志等横切关注

实现AOP有几种方式:

1. Spring 1.2版本中通过ProxyFactoryBean来实现aop,即通过动态代理来实现的,Aspect必须继承MethodBeforeAdvice,MethodAfterAdvice等

2. Spring 2.0 AOP需要改的是FBI 这个类,而且它也不需要再实现某些接口

3. 三使用标注(@AspectJ)实现AOP


AOP 和 OOP的区别:

1. 面向方面编程 AOP 偏重业务处理过程的某个步骤或阶段,强调降低模块之间的耦合度,使代码拥有更好的移植性。

2. 面向对象编程 (oop) 则是对业务分析中抽取的实体进行方法和属性的封装。

也可以说 AOP 是面向业务中的动词领域, OOP 面向名词领域。

AOP 的一个很重要的特点是源代码无关性,也就是说如果我们的系统中引用了 AOP 组件,即使我们把该组件去掉,系统代码也应该能够编译通过。要实现这一点,可以使用动态 proxy 模式。


AOP将散落在系统中的“方面”代码集中实现;AOP有助于提高系统可维护性;AOP是一种设计模式,Spring提供了一种实现;


2.PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。


3.Spring的依赖注入:

依赖注入通常有如下两种:设置注入和构造注入:

构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入

设值注入是指IoC容器使用属性的setter方法来注入被依赖的实例。这种注入方式比较简单、直观


4.DispatcherServlet是前端控制器设计模式的实现,提供Spring Web MVC的集中访问点,而且负责职责的分派,

而且与Spring IoC容器无缝集成,从而可以获得Spring的所有好处。

DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责如下:

1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析;

2、通过HandlerMapping,将请求映射到处理器(返回一个HandlerExecutionChain,它包括一个处理器、多个HandlerInterceptor拦截器);

3、  通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器);

4、通过ViewResolver解析逻辑视图名到具体视图实现;

5、本地化解析;

6、渲染具体的视图等;

7、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析。

Spring MVC的核心控制器DispatcherServlet它负责接收HTTP请求,加载配置文件,初始化上下应用对象ApplicationContext。


5.在J2EE中,使用Servlet过滤器,需要在web.xml中配置<filter>(过滤器),<filter-mapping>(过滤器映射)元素。


6.Servlet接口的方法有init方法。

Servlet的方法有init() 、 destroy() ,doGet(),doPost()等方法


7.Spring框架中的核心思想包括依赖注入,控制反转,面向切面。


8.在Spring框架中获取连接池的方式:

DBCP数据源

C3P0数据源

Spring的数据源实现类(DriverManagerDataSource)

获取JNDI数据源


9.在Servlet里,能实现重定向的方法是:

运用javax.servlet.http.HttpServletResponse接口的sendRedirect方法.

sendRedirect方法 是重定向

forward方法  是请求转发


10.sendRedirect():

重定向,让客户完成工作,即地址栏发生改变,可以转向外部资源。 该方法参数为String。使用相对URL作为参数。带/的相对原先的URL建立完整URL。不带/的相对Web应用建立。

 forward ( ):

 请求分派,服务器的内部转发,对客户是透明的(地址栏不发生改变)。

基于Servlet API可以通过forward方法实现转向时不在地址栏中显示转向后的地址


11.1. Java Servlet API 中引用 Session 机制来追踪客户的状态。Servlet API 中定义了 javax.servlet.http.HttpSession 接口,Servlet 容器必须实现这个接口。

2.当一个 Session 开始时,Servlet 容器将创建一个 HttpSession 对象,Servlet 容器为 HttpSession 分配一个唯一标识符,称为 Session ID。Servlet 容器将 Session ID 作为 Cookie 保存在客户的浏览器中。每次客户发出 HTTP 请求时,Servlet 容器可以从 HttpRequest 对象中读取 Session ID,然后根据 Session ID 找到相应的 HttpSession 对象,从而获取客户的状态信息。

3.当客户端浏览器中禁止 Cookie,Servlet 容器无法从客户端浏览器中取得作为 Cookie 的 Session ID,也就无法跟踪客户状态。  

Java Servlet API 中提出了跟踪 Session 的另一种机制,如果客户端浏览器不支持 Cookie,Servlet 容器可以重写客户请求的 URL,把 Session ID 添加到 URL 信息中。  

4. HttpServletResponse 接口提供了重写 URL 的方法:public java.lang.String encodeURL(java.lang.String url)  

该方法的实现机制为:   

● 先判断当前的 Web 组件是否启用 Session,如果没有启用 Session,直接返回参数 url。   

● 再判断客户端浏览器是否支持 Cookie,如果支持 Cookie,直接返回参数 url;如果不支持 Cookie,就在参数 url 中加入 Session ID 信息,然后返回修改后的 url。   

我们可以对网页中的链接稍作修改,解决以上问题:

修改前:

<a href=“maillogin.jsp“>   

修改后:  

<a href=“<%=response.encodeURL(“maillogin.jsp“)%>“>    


12.事务属性的种类:传播行为、隔离级别、只读和事务超时

a)传播行为定义了被调用方法的事务边界。

 

传播行为     意义

1.PROPERGATION_MANDATORY

表示方法必须运行在一个事务中,如果当前事务不存在,就抛出异常

2.PROPAGATION_NESTED

表示如果当前事务存在,则方法应该运行在一个嵌套事务中。

3.PROPAGATION_NEVER

表示方法不能运行在一个事务中,否则抛出异常

4.PROPAGATION_NOT_SUPPORTED

表示方法不能运行在一个事务中,如果当前存在一个事务,则该方法将被挂起

5.PROPAGATION_REQUIRED

表示当前方法必须运行在一个事务中,如果当前存在一个事务,那么该方法运行在这个事务中,否则,将创建一个新的事务

6.PROPAGATION_REQUIRES_NEW

表示当前方法必须运行在自己的事务中,如果当前存在一个事务,那么这个事务将在该方法运行期间被挂起

7.PROPAGATION_SUPPORTS

表示当前方法不需要运行在一个是事务中,但如果有一个事务已经存在,该方法也可以运行在这个事务中

 

b) 隔离级别

在操作数据时可能带来 3 个副作用,分别是脏读、不可重复读、幻读。

为了避免这 3 中副作用的发生,在标准的 SQL 语句中定义了 4 种隔离级别,

分别是未提交读、已提交读、可重复读、可序列化。

而在 spring 事务中提供了5种隔离级别来对应在 SQL 中定义的 4 种隔离级别,

如下:

隔离级别     意义

1.ISOLATION_DEFAULT  使用后端数据库默认的隔离级别

2.ISOLATION_READ_UNCOMMITTED

允许读取未提交的数据(对应未提交读),可能导致脏读、不可重复读、幻读

3.ISOLATION_READ_COMMITTED

允许在一个事务中读取另一个已经提交的事务中的数据(对应已提交读)。可以避免脏读,但是无法避免不可重复读和幻读

4.ISOLATION_REPEATABLE_READ

一个事务不可能更新由另一个事务修改但尚未提交(回滚)的数据(对应可重复读)。

可以避免脏读和不可重复读,但无法避免幻读

5.ISOLATION_SERIALIZABLE

这种隔离级别是所有的事务都在一个执行队列中,依次顺序执行,而不是并行(对应可序列化)。可以避免脏读、不可重复读、幻读。但是这种隔离级别效率很低,因此,除非必须,否则不建议使用。

 

c)只读

如果在一个事务中所有关于数据库的操作都是只读的,也就是说,这些操作只读取数据库中的数据,而并不更新数据,那么应将事务设为只读模式(READ_ONLY_MARKER) , 这样更有利于数据库进行优化 。

因为只读的优化措施是事务启动后由数据库实施的,因此,只有将那些具有可能启动新事务的传播行为 (PROPAGATION_NESTED 、 PROPAGATION_REQUIRED 、 PROPAGATION_REQUIRED_NEW) 的方法的事务标记成只读才有意义。

如果使用 Hibernate 作为持久化机制,那么将事务标记为只读后,会将 Hibernate 的 flush 模式设置为 FULSH_NEVER, 以告诉 Hibernate 避免和数据库之间进行不必要的同步,并将所有更新延迟到事务结束。

d) 事务超时

如果一个事务长时间运行,这时为了尽量避免浪费系统资源,应为这个事务设置一个有效时间,使其等待数秒后自动回滚。

与设置“只读”属性一样,事务有效属性也需要给那些具有可能启动新事物的传播

行为的方法的事务标记成只读才有意义。


13.Spring特性中IoC的描述:

所谓“控制反转”是指控制权由应用代码转到外部容器,即控制权的转移。

IoC将控制创建的职责搬进了框架中,从应用代码脱离开来。

使用Spring的IoC容器时只需指出组件需要的对象,在运行时Spring的IoC容器会根据XML配置数据提供给它。


14.Spring框架模块,七大模块,如下:

1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。

2.Spring Context: 构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。

3.Spring DAO:  DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。

4.Spring ORM: ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate 和 iBatis 。

利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,

如前边提到的简单声明性事务管理。

5.Spring AOP: Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。

6.Spring Web: Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。

7.Spring Web MVC: Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。


15.spring对bean的生命周期的描述:

如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,

工厂调用setBeanFactory()方法传入工厂自身。

可以在Bean定义文件中使用"init-method"属性,

rg.springframework.beans.factory.DisposableBean接口,

则执行他的destroy()方法。


创建:<bean name=”” class=”” 额外属性>

初始化:配置init-method/实现接口InitializingBean

调用:context.getBean(),进行方法的调用

销毁:配置destroy-method/实现DisposableBean接口。


16.Spring提供的DAO(数据访问对象)支持主要的目的是便于以标准的方式使用不同的数据访问技术。 

简化 DAO 组件的开发。 

Spring提供了一套抽象DAO类供你扩展。这些抽象类提供了一些方法,用来简化代码开发。 IoC 容器的使用,提供了 DAO 组件与业务逻辑组件之间的解耦。所有的 DAO 组件,都由容器负责注入到业务逻辑组件中,其业务组件无须关心 DAO 组件的实现。 面向接口编程及 DAO 模式的使用,提高了系统组件之间的解耦,

降低了系统重构的成本。 

方便的事务管理: Spring的声明式事务管理力度是方法级。 

异常包装:Spring能够包装Hibernate异常,把它们从CheckedException变

为RuntimeException; 开发者可选择在恰当的层处理数据中不可恢复的异常,

从而避免烦琐的 catch/throw 及异常声明。

Spring提供的DAO支持了JDBC、JDO和Hibernate。


17.spring mvc 和struts2的区别:

1.spring mvc是基于方法的设计,而struts2是基于类的设计。

2.struts2有以自己的interceptor机制,spring mvc用的是独立的AOP方式。

3.spring mvc的方法之间基本上独立的,独享request response数据,struts2所有Action变量是共享的。

4.机制:spring mvc的入口是servlet,而struts2是filter。 

补充几点知识: 

《 Filter 实现javax.servlet.Filter接口,在web.xml中配置与标签指定使用哪个

Filter实现类过滤哪些URL链接。只在web启动时进行初始化操作。 

filter 流程是线性的,url传来之后,检查之后,可保持原来的流程继续向下执行,

被下一个filter, servlet接收等,而servlet 处理之后,不会继续向下传递。

filter功能可用来保持流程继续按照原来的方式进行下去,或者主导流程,而servlet的功能主要用来主导流程。  

特点:可以在响应之前修改Request和Response的头部,只能转发请求,不能直接发出响应。

filter可用来进行字符编码的过滤,检测用户是否登陆的过滤,禁止页面缓存等》 《 Servlet, servlet 流程是短的,url传来之后,就对其进行处理,之后返回或转向到某一自己指定的页面。它主要用来在业务处理之前进行控制 》 

《 Listener呢?我们知道 servlet、filter都是针对url之类的,而listener是针对对象的操作的,如session的创建,session.setAttribute的发生,在这样的事件发 生时做一些事情。 》  

5.性能:spring会稍微比struts快。 spring mvc是基于方法的设计 , 而sturts是基于类 ,每次发一次请求都会实例一个action,每个action都会被注入属性,而spring基于方法,粒度更细(粒度级别的东西比较sychronized和lock),但要小心把握像在servlet控制数据一样。 

 spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,在spring3 mvc中,一个方法对应一个request上下文。 而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入;struts2实际上是通过setter getter方法与request打交道的;struts2中,一个Action对象对应一个request上下文。 

6. 参数传递:struts是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。

7. 设计思想上: struts更加符合oop的编程思想 , spring就比较谨慎,在servlet上扩展。 

8. intercepter(拦截器)的实现机制:struts有以自己的interceptor机制, spring mvc用的是独立的AOP方式 。这样导致struts的配置文件量还是比spring mvc大,虽然struts的配置能继承,所以我觉得,就拿使用上来讲,spring mvc使用更加简洁, 开发效率Spring MVC确实比struts2高 。 spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上 spring3 mvc就容易实现restful url 。 struts2是类级别的拦截,一个类对应一个request上下文;实现restful url要费劲,因为struts2 action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3 mvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量, 而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。 

9. 另外,spring3 mvc的验证也是一个亮点,支持JSR303, 处理ajax的请求更是方便 ,只需一个注解 @ResponseBody  ,然后直接返回响应文本即可。 


18.spring的IOC容器能够帮我们自动new对象,对象交给spring管之后我们不用自己手动去new对象了,也就是控制权的转让。

spring使用BeanFactory来实例化、配置和管理对象,但是它只是一个接口,里面有一个getBean()方法。

我们一般都不直接用BeanFactory,而是用它的实现类 ApplicationContext ,这个类会自动解析我们配置的applicationContext.

spring依赖注入:

IOC就是由spring来负责控制对象的生命周期和对象间的关系。

BeanFacotry是最简单的容器,提供了基础的依赖注入支持。 ApplicationContext建立在BeanFacotry之上,提供了系统构架服务。


19.spring没有提供AOP方式的日志系统

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

Spring通过对AOP的支持,借助log4j等Apache开源组件实现了日志系统。

Spring是一系列轻量级Java EE框架的集合。Spring中包含一个“依赖注入”模式的实现。使用Spring可以实现声明式事务。


20.Servlet是一个特殊的Java类,它必须直接或间接实现Servlet接口。

Servlet客户线程调用service方法响应客户的请求。 servlet接口定义了servlet的生命周期方法:init()、service()、destory()三个方法 当多个浏览器终端请求web服务器的时候,服务器为每个客户启动一个线程,不是进程。 import javax.servlet.http.httpservletrequest,你看这个包说明servlet是一个特殊的Java类, java和javax都是Java的API包,java是核心包,javax的x是extension的意思,也就是扩展包。  


21.Spring的特色之一,简单而强大的事务管理功能,包括编程式事务和声明式事务。

1. Spring中涉及到事务管理的API有100多个,核心的只有三个: TransactionDefinition、PlatformTransactionManager、TransactionStatus。所谓事务管理,其实就是“按照给定的事务规则来执行提交或者回滚操作”。“给定的事务规则”就是用 TransactionDefinition 表示的,“按照……来执行提交或者回滚操作”便是用 PlatformTransactionManager 来表示,而 TransactionStatus 用于表示一个运行着的事务的状态。

2. TransactionDefinition, 该接口在前面已经介绍过,它用于定义一个事务。它包含了事务的静态属性,比如:事务传播行为、超时时间等等。Spring 为我们提供了一个默认的实现类:DefaultTransactionDefinition,该类适用于大多数情况。如果该类不能满足需求,可以通过实现 TransactionDefinition 接口来实现自己的事务定义。

3. PlatformTransactionManager  用于执行具体的事务操作。

Public interface PlatformTransactionManager{

   TransactionStatus getTransaction(TransactionDefinition definition)  throws TransactionException;

   void commit(TransactionStatus status)throws TransactionException;

   void rollback(TransactionStatus status)throws TransactionException;

}

根据底层所使用的不同的持久化 API 或框架,PlatformTransactionManager 的主要实现类大致如下:

DataSourceTransactionManager :适用于使用JDBC和iBatis进行数据持久化操作的情况。

HibernateTransactionManager :适用于使用Hibernate进行数据持久化操作的情况。

JpaTransactionManager :适用于使用JPA进行数据持久化操作的情况。

另外还有JtaTransactionManager 、JdoTransactionManager、JmsTransactionManager等等。

4. 编程式事务需要你在代码中直接加入处理事务的逻辑,可能需要在代码中显式调用beginTransaction()、commit()、rollback()等事务管理相关的方法,如在执行a方法时候需要事务处理,你需要在a方法开始时候开启事务,处理完后。在方法结束时候,关闭事务. 声明式的事务的做法是在a方法外围添加注解或者直接在配置文件中定义,a方法需要事务处理,在spring中会通过配置文件在a方法前后拦截,并添加事务. 二者区别.编程式事务侵入性比较强,但处理粒度更细. 相当于一个是手动事务,另一个是系统自动事务。 编程试事务就是需要手工写代码提交事务,回滚事务等。 声明性事务就是在配置文件里面定义一下什么时候需要事务,到时候系统会自动commit,出异常了自动rollback,不需要在代码里面写commit或者rollback。


spring事务:

spring事务可以分为编程式事务和声明式事务。

spring提供了一个事务的接口 PaltformTractionManager接口,针对不同的事务,spring进行了不同的实现。

声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码。





本文出自 “11029145” 博客,请务必保留此出处http://11039145.blog.51cto.com/11029145/1885619

以上是关于Java之Spring知识点的主要内容,如果未能解决你的问题,请参考以下文章

Spring基础知识之装配Bean

Spring知识点总结之Spring IOC

Spring之bean的生命周期

Java知识体系!2021最新Java面试题目解答,轻松拿下offer

万字详解Spring之IOC全部知识点

[原创]spring源码解析之前置知识点