Java面试分享(题目+答案)

1.说下Struts的设计模式

MVC模式: 
web应用程序启动时
就会加载并初始化ActionServler。
用户提交表单时,
一个配置好的ActionForm对象被创建,
并被填入表单相应的数据,
ActionServler根据Struts-config.xml文件
配置好的设置决定是否需要表单验证,
如果需要就调用ActionForm的Validate()
验证后选择将请求发送到哪个Action,
如果Action不存在,
ActionServlet会先创建这个对象,
然后调用Action的execute()方法。
Execute()从ActionForm对象中获取数据,
完成业务逻辑,
返回一个ActionForward对象,
ActionServlet再把客户请求 
转发给ActionForward对象指定的jsp组件,
ActionForward对象指定的jsp生
成动态的网页,返回给客户。

2.拦截器和过滤器的区别?

1、拦截器是基于java反射机制的,
而过滤器是基于函数回调的。

2、过滤器依赖于servlet容器,
而拦截器不依赖于servlet容器。

3、拦截器只能对Action请求起作用,
而过滤器则可以对几乎所有请求起作用。

4、拦截器可以访问Action上下文、
值栈里的对象,而过滤器不能。

5、在Action的生命周期中,
拦截器可以多次调用,
而过滤器只能在容器初始化时被调用一次。

3.struts2框架的核心控制器是什么?它有什么作用?

1)Struts2框架的核心控制器是
StrutsPrepareAndExecuteFilter。  

2)作用:  

 负责拦截由<url-pattern>/*</url-pattern>
指定的所有用户请求,
当用户请求到达时,
该Filter会过滤用户的请求。
默认情况下,
如果用户请求的路径  

不带后缀或者后缀以.action结尾,
这时请求将被转入struts2框架处理,
否则struts2框架将略过该请求的处理。  

可以通过常量"struts.action.extension"修改action的后缀,
如:  
<constant name="struts.action.extension" value="do"/>  
如果用户需要指定多个请求后缀,
则多个后缀之间以英文逗号(,)隔开。
<constant name="struts.action.extension" value="do,go"/>

4.struts2如何访问HttpServletRequest、HttpSession、ServletContext三个域对象?

方案一:  

HttpServletRequest request =
ServletActionContext.getRequest();  

HttpServletResponse response =
ServletActionContext.getResponse();  

HttpSession  session=   
request.getSession(); 

ServletContext servletContext=
ServletActionContext.getServletContext();  



方案二:  

类 implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware  

注意:框架自动传入对应的域对象

5.ActionContext、ServletContext、pageContext的区别?

1)ActionContext是当前的Action的上下文环境,
通过ActionContext可以
获取到request、session、ServletContext等
与Action有关的对象的引用;  

2)ServletContext是域对象,
一个web应用中只有一个ServletContext,
生命周期伴随整个web应用;  

3)pageContext是JSP中的最重要的一个内置对象,
可以通过pageContext获取其他域对象的应用,
同时它是一个域对象,
作用范围只针对当前页面,
当前页面结束时,
pageContext销毁,  

生命周期是JSP四个域对象中最小的。

6.描述Struts2的工作原理

客户端发送请求--》
请求经过一系列过滤器->
FilterDispatcher通过
ActionMapper来决定这个Reques
t需要调用哪个Action ->
FilterDispatcher把请求的处理交给ActionProxy-> 
通过ConfigurationManager询问
Struts配置文件(Struts.xml)
找到需要调用的Action类->
ActionProxy创建一个ActionInvocation的实例 ->
调用Action->执行完毕,
返回结果

7.result的type属性中有哪几种结果类型?

一共10种:    

dispatcher          

struts默认的结果类型,
把控制权转发给应用程序里的
某个资源不能把控制权
转发给一个外部资源,
若需要把控制权重定向到
一个外部资源, 应该使用  

redirect结果类型  
redirect   
把响应重定向到另一个资源(包括一个外部资源)  

redirectAction      
把响应重定向到另一个 Action  

freemarker、
velocity、
chain、
httpheader、
xslt、
plainText、
stream

8.拦截器的生命周期与工作过程?

1)每个拦截器都是实现了I
nterceptor接口的 Java 类;  

2)init(): 该方法将在拦截器被创建后立即被调用, 
它在拦截器的生命周期内只被调用一次. 
可以在该方法中对相关资源
进行必要的初始化;  

3)intercept(ActionInvocation invocation): 
每拦截一个动作请求,
 该方法就会被调用一次;  

4)destroy: 
该方法将在拦截器被销毁之前被调用, 
它在拦截器的生命周期内也只被调用一次;  

5)struts2中有内置了18个拦截器。

9.struts2如何完成文件的上传?

1、JSP页面:  

1)JSP页面的上传文件的组件:
<s: file name=”upload” />,
如果需要一次上传多个文件, 
就必须使用多个 file 标签, 
但它们的名字必须是相同的,
即:   name=“xxx”的值必须一样;  

2)必须把表单的enctype属性设置为:
multipart/form-data;  

 3)表单的方法必须为post,
因为post提交的数据在消息体中,
而无大小限制。  

2、对应的action:  

 1)在 Action 中新添加 3 个
和文件上传相关的属性;  

2)如果是上传单个文件, 
uploadImage属性的类型就是 
java.io.File, 它代表被上传的文件, 
第二个和第三个属性的类型是 String, 
它们分别代表上传文 件的文件名和文件类型,
定义方式是分别是:  

jsp页面file组件的名称+ContentType,  
jsp页面file组件的名称+FileName  

3)如果上上传多个文件, 
可以使用数组或 List

10.值栈ValueStack的原理与生命周期?

1)ValueStack贯穿整个 Action 的生命周期,
保存在request域中,
所以ValueStack和request的生命周期一样。
当Struts2接受一个请求时,
会迅速创建ActionContext,  

ValueStack,action。
然后把action存放进ValueStack,
所以action的实例变量可以被OGNL访问。
 请求来的时候,
action、ValueStack的生命开始,
请求结束,action、    ValueStack的生命结束;  

2)action是多例的,和Servlet不一样,
Servelt是单例的;  

3)每个action的都有一个对应的值栈,
值栈存放的数据类型是该action的实例,
以及该action中的实例变量,
Action对象默认保存在栈顶;  

4)ValueStack本质上就是一个ArrayList;  

5)关于ContextMap,
Struts 会把下面这些映射压入 ContextMap 中:  

parameters  :   
该 Map 中包含当前请求的请求参数  

request     :  
该 Map 中包含当前 request 对象中的
所有属性  session 
:该 Map 中包含当前 session 对象中的所有属性  

application 
:该 Map 中包含当前 
application 对象中的所有属性  

attr:该 Map 按如下顺序来检索某个属性: 
request, session, application           

6)使用OGNL访问值栈的内容时,
不需要#号,
而访问request、session、application、attr时,
需要加#号;  

7)注意: Struts2中,
OGNL表达式需要配合Struts标签才可以使用。
如:<s:property value="name"/>  

8)在struts2配置文件中引用ognl表达式 ,
引用值栈的值 ,此时使用的"$",而不是#或者%;

11.Struts2中的拦截器有什么用?列举框架提供的拦截器名称?

1)拦截器是struts2核心组成部分,
它提供了一种机制,使得开发者
可以定义一个特定的功能模块,
这个模块会在Action执行之前或者之后执行
也可以在Action执行之前阻止Action执行。 

 2)常用的拦截器有: 

 chain:在不同请求之间将请求参数在不同名字件转换,
请求内容不变 

 fileUpload:提供文件上传。 

 i18n:记录用户选择的区域环境 

 logger:输出Action的名字

 params:将请求中的参数设置到Action中去。

12.Struts2有哪些优点?

1)在软件设计上Struts2的应用
可以不依赖于Servlet API和struts API。 
Struts2的这种设计属于无侵入式设计; 

 2)拦截器,
实现如参数拦截注入等功能;

 3)类型转换器,
可以把特殊的请求参数转换成需要的类型; 

 4)多种表现层技术,
如:JSP、freeMarker、Velocity等;

 5)Struts2的输入校验
可以对指定某个方法进行校验;

 6)提供了全局范围、
包范围和Action范围的
国际化资源文件管理实现 

 7) 实现MVC模式,结构清晰,
使开发者只关注业务逻辑的实现。
有丰富的tag可以用,
大提高了开发效率。(简要)

13.ActionContext和ValueStack什么时候创建?是否是线程安全的?

明确:
动作类是多例的,
每次动作访问,
动作类都会实例化。
所以是线程安全的。
与Struts1的区别是,
struts1的动作类是单例的。

在每次动作执行前,
核心控制器StrutsPrepareAndExecuteFilter
都会创建一个ActionContext和ValueStack对象。
且每次动作访问都会创建。

 这两个对象存储了整个动作
访问期间用到的数据。
并且把数据绑定到了线程局部变量
ThreadLocal上了。
所以是线程安全的。

14.一个请求在Struts2框架中的处理大概分为几个步骤?

1) 客户端初始化一个
指向Servlet容器(例如Tomcat)的请求

2 )这个请求经过一系列的过滤器Filter
这些过滤器中有一个叫做
ActionContextCleanUp的可选过滤器,
这个过滤器对于Struts2和
其他框架的集成很有帮助,
例如:SiteMesh Plugin)

3 )接着FilterDispatcher被调用,
FilterDispatcher询问ActionMapper
来决定这个请是否需要调用某个Action

4 )如果ActionMapper决定需要调用某个Action,
FilterDispatcher把请求的处理交给ActionProxy

5 )ActionProxy通过Configuration Manager
询问框架的配置文件,
找到需要调用的Action类

6 )ActionProxy创建一个ActionInvocation的实例。

7 )ActionInvocation实例使用命名模式来调用,
在调用Action的过程前后,
涉及到相关拦截器(Intercepter)的调用。

 8 )一旦Action执行完毕,
ActionInvocation负责根据struts.xml中的配置
找到对应的返回结果。
返回结果通常是一个需要
被表示的JSP或者FreeMarker的模版。
在表示的过程中可以使用Struts2 框架中
继承的标签。
在这个过程中需要涉及到ActionMapper

15.介绍一下Struts的ActionServlet类

ActionServlet继承自
javax.servlet.http.HttpServlet类,
其在Struts framework中扮演的角色
是中心控制器。
它提供一个中心位置来处理全部的终端请求。
控制器ActionServlet主要
负责将HTTP的客户请求信息组装后,
根据配置文件的指定描述,
转发到适当的处理器。
按照Servelt的标准,
所有得Servlet必须在
web配置文件(web.xml)声明。
同样,ActoinServlet必须在
Web Application配置文件(web.xml)中描述
当用户向服务器端提交请求的时候,
实际上信息是首先发送到控制器ActionServlet,
一旦控制器获得了请求,
其就会将请求信息传交给一些辅助类(help classes)处理。
这些辅助类知道如何去处理与请求信息所对应的业务操作。
在Struts中,
这个辅助类就是org.apache.struts.action.Action。
通常开发者需要自己继承Aciton类,
从而实现自己的Action实例。

16.Spring是什么?

他解决的是业务逻辑层和其他各层的松耦合问题,
因此它将面向接口的编程思想
贯穿整个系统应用。

 Spring是一个轻量级的IoC和AOP容器框架。
目的是解决企业应用开发的复杂性,
使用基本的JavaBean来完成
以前只可能由EJB完成的事情,
并提供了更多的企业应用功能,
Spring的用途不仅限于服务器端的开发,
从简单性、
可测试性和松耦合的角度而言,
任何Java应用都可以从Spring中受益。

17.说说Spring 的优点?

1.spring属于低侵入式设计,
代码的污染极低;

2.spring的DI机制降低了
业务对象替换的复杂性;

3.容器提供了AOP技术,
利用它很容易实现如权限拦截,
运行期监控等功能;

4.降低了组件之间的耦合性 ,
实现了软件各层之间的解耦; 

5.容器提供单例模式支持;

6.可以使用容器提供的众多服务,
如事务管理,消息服务等;

7.容器提供了众多的辅助类,
能加快应用的开发;

8.spring对于主流的应用框架提供了集成支持,
如hibernate,JPA,Struts等 

9.独立于各种应用服务器 

10.Spring的高度开放性,
并不强制应用完全依赖于Spring,
开发者可以自由选择spring的部分或全部。

18.说说你对Spring的IoC与DI的理解

(1)IOC就是控制反转。
就是对象的创建权反转交给Spring,
由容器控制程序之间的依赖关系,
作用是实现了程序的解耦合,
而非传统实现中,
由程序代码直接操控。
(依赖)控制权由应用代码本身转到了外部容器,
由容器根据配置文件去创建实例
并管理各个实例之间的依赖关系,
控制权的转移,
是所谓反转,
并且由容器动态的将某种依赖关系注入到组件之中。
BeanFactory 是Spring IoC容器的具体实现与核心接口,
提供了一个先进的配置机制,
使得任何类型的对象的配置成为可能,
用来包装和管理各种bean。

2.最直观的表达就是,
IOC让对象的创建不用去new了,
可以由spring自动生产,
这里用的就是java的反射机制,
通过反射在运行时动态的去创建、
调用对象。
spring就是根据配置文件
在运行时动态的去创建对象,
并调用对象的方法的。

3.Spring的IOC有三种注入方式 : 
第一是根据属性注入,也叫set方法注入; 
 第二种是根据构造方法进行注入; 
第三种是根据注解进行注入。

详细的说:
IOC控制反转:
将对象交给容器管理,
你只需要在spring配置文件总配置相应的bean,
以及设置相关的属性,
让spring容器生成类的实例对象以及管理对象。
在spring容器启动的时候,
spring会把你在配置文件中配
置的bean都初始化以及装配好,
然后在你需要调用的时候,
就把它已经初始化好的那些bean
分配给你需要调用这些bean的类。
就是将对象的控制权反转给spring容器管理。

DI机制(Dependency Injection,依赖注入):
可以说是IoC的其中一个内容,
在容器实例化对象的时候
主动的将被调用者(或者说它的依赖对象)
注入给调用对象。
比如对象A需要操作数据库,
以前我们总是要在A中
自己编写代码来获得一个Connection对象,
有了 spring我们就只需要告诉spring,
A中需要一个Connection,
至于这个Connection怎么构造,
何时构造,
A不需要知道。
在系统运行时,
spring会在适当的时候制造一个Connection,
然后像打针一样,注射到A当中,
这样就完成了对各个对象之间关系的控制。

19.解释Spring支持的几种bean的作用域

Spring容器中的bean可以分为5个范围:
1.singleton:这种bean范围是默认的,
这种范围确保不管接受到多少个请求,
每个容器中只有一个bean的实例,
单例的模式由bean factory自身来维护。

2.prototype:原形范围与单例范围相反,
为每一个bean请求提供一个实例。

3.request:在请求bean范围内
会每一个来自客户端的网络请求创建一个实例,
在请求完成以后,
bean会失效并被垃圾回收器回收。

4.Session:与请求范围类似,
确保每个session中有一个bean的实例,
在session过期后,
bean会随之失效。

5.global-session:
global-session和Portlet应用相关。
当你的应用部署在Portlet容器中工作时,
它包含很多portlet。
如果你想要声明让所有的portlet
共用全局的存储变量的话,
那么这全局变量需要存储在global-session中。
全局作用域与Servlet中的session
作用域效果相同。

20.BeanFactory 接口和 ApplicationContext 接口有什么区别 ?

BeanFactory和ApplicationContext
是Spring的两大核心接口,
而其中ApplicationContext是BeanFactory的子接口。
它们都可以当做Spring的容器,
生成Bean实例的,
并管理容器中的Bean。

1.BeanFactory:
是Spring里面最底层的接口,
提供了最简单的容器的功能,
负责读取bean配置文档,
管理bean的加载与实例化,
维护bean之间的依赖关系,
负责bean的生命周期,
但是无法支持spring的aop功能和web应用。

2.ApplicationContext接口
作为BeanFactory的派生,
因而具有BeanFactory所有的功能。
而且ApplicationContext还在功能上做了扩展,
以一种更面向框架的方式工作以及对上下文进行分层和实现继承,
相较于BeanFactorty,
ApplicationContext还提供了以下的功能: 
①默认初始化所有的Singleton,也可以通过配置取消预初始化。
②继承MessageSource,因此支持国际化。
③资源访问,比如访问URL和文件。
④事件机制。
⑤同时加载多个配置文件。
⑥以声明式方式启动并创建Spring容器。
⑦载入多个(有继承关系)上下文 ,
使得每一个上下文
都专注于一个特定的层次,
比如应用的web层。

BeanFactroy采用的是延迟加载形式
来注入Bean的,
即只有在使用到某个Bean时(调用getBean()),
才对该Bean进行加载实例化,
这样,我们就不能发现一些存在的Spring的配置问题。
如果Bean的某一个属性没有注入,B
eanFacotry加载后,
直至第一次使用调用getBean方法
才会抛出异常。

而ApplicationContext则相反,
它是在容器启动时,
一次性创建了所有的Bean。
这样,在容器启动时,
我们就可以发现Spring中存在的配置错误,
这样有利于检查所依赖属性是否注入。 
ApplicationContext启动后
预载入所有的单实例Bean,
通过预载入单实例bean ,
确保当你需要的时候,
你就不用等待,
因为它们已经创建好了。

相对于基本的BeanFactory,
ApplicationContext 唯一的不足是
占用内存空间。
当应用程序配置Bean较多时,
程序启动较慢。

BeanFactory通常以编程的方式被创建,
ApplicationContext还能以声明的方式创建,
如使用ContextLoader。

BeanFactory和ApplicationContext
都支持BeanPostProcessor、
BeanFactoryPostProcessor的使用,

但两者之间的区别是:
BeanFactory需要手动注册,
而ApplicationContext则是自动注册。

21.请解释Spring Bean的生命周期?

首先说一下Servlet的生命周期:
实例化,
初始init,
接收请求service,
销毁destroy;

 Spring上下文中的Bean生命周期也类似,
如下:
1.实例化一个Bean
也就是我们常说的new;

2.按照Spring上下文
对实例化的Bean进行配置
也就是IOC注入;

3.如果这个Bean已经实现了BeanNameAware接口,
会调用它实现的
setBeanName(String)方法,
此处传递的就是Spring配置文件中Bean的id值;

4.如果这个Bean已经实现了BeanFactoryAware接口,
会调用它实现的
setBeanFactory(setBeanFactory(BeanFactory)
传递的是Spring工厂自身
可以用这个方式来获取其它Bean,
只需在Spring配置文件中
配置一个普通的Bean就可以;

5.如果这个Bean已经实现了
ApplicationContextAware接口,
会调用setApplicationContext(ApplicationContext)方法,
传入Spring上下文
同样这个方式也可以实现步骤4的内容,
但比4更好,
因为ApplicationContext是BeanFactory的子接口,
有更多的实现方法

6.如果这个Bean关联了
BeanPostProcessor接口,
将会调用
postProcessBeforeInitialization(Object obj, String s)方法,
BeanPostProcessor
经常被用作是Bean内容的更改,
并且由于这个是在Bean初始化结束时
调用那个的方法,
也可以被应用于内存或缓存技术;

7.如果Bean在Spring配置文件中
配置了init-method属性
会自动调用其配置的初始化方法。

8.如果这个Bean关联了BeanPostProcessor接口,
将会调用
postProcessAfterInitialization(Object obj, String s)方法、;

注:以上工作完成以后就可以应用这个Bean了,
那这个Bean是一个Singleton的,
所以一般情况下
们调用同一个id的Bean会是
在内容地址相同的实例,
当然在Spring配置文件中
也可以配置非Singleton。

9.当Bean不再需要时,
会经过清理阶段,
如果Bean实现了DisposableBean这个接口,
会调用那个其实现的destroy()方法;

10.最后,
如果这个Bean的Spring配置中
配置了destroy-method属性,
会自动调用其配置的销毁方法。

 另外我们这里描述的是应用Spring
上下文Bean的生命周期,
如果应用Spring的工厂
也就是BeanFactory的话去掉第5步就Ok了。

22.介绍下Spring的主要模块?

Spring AOP:
Spring的关键组件之一是AOP框架。
AOP在Spring中使用:
提供声明性的企业服务,
特别是作为EJB声明式服务的替代品。
最重要的服务是声明式事务管理,
它建立在Spring的事务抽象之上。
允许用户实现自定义的切面,
补充他们使用AOP的OOP的使用。

Spring ORM:
ORM包与数据库访问有关。
它为流行的对象关系映射api提供集成层,
包括JDO、Hibernate和iBatis。

Spring Web:
web应用程序开发堆栈,
其中包括Spring MVC。

Spring DAO:
Spring的DAO(Data Access Object)
支持主要用于使用JDBC、
Hibernate或JDO等
技术标准化数据访问工作。

Spring Context:
此包构建在bean包之上,
以增加对消息源的支持和观察者的设计模式支持,
以及应用程序对象使用一致的
API获得资源的能力。

Spring Web MVC:
这是为web应用程序
提供MVC实现的模块。

Spring Core:
核心包是Spring框架中最重要的组件。

该组件提供依赖性注入特性。
BeanFactory提供了一种工厂模式,
它将诸如初始化、
创造和访问对象
与实际程序逻辑的访问分离开来。

23.Spring事务的种类和各自的区别?

spring支持
编程式事务管理
声明式事务管理
两种方式:

1.编程式事务管理使用TransactionTemplate
或者直接使用底层的PlatformTransactionManager。
对于编程式事务管理,
spring推荐使用TransactionTemplate。

2.声明式事务管理建立在AOP之上的。
其本质是对方法前后进行拦截,
然后在目标方法开始之前创建或者加入一个事务,
在执行完目标方法之后
根据执行情况提交或者回滚事务。
声明式事务最大的优点
就是不需要通过编程的方式管理事务,
这样就不需要在业务逻辑代码中
掺杂事务管理的代码,
只需在配置文件中
做相关的事务规则声明
或通过基于@Transactional注解的方式
便可以将事务规则应用到业务逻辑中。

3.显然声明式事务管理要优于编程式事务管理,
这正是spring倡导的非侵入式的开发方式。
声明式事务管理使业务代码不受污染,
一个普通的POJO对象,
只要加上注解就可以获得完全的事务支持。
和编程式事务相比,
声明式事务唯一不足地方是,
后者的最细粒度只能作用到方法级别,
无法做到像编程式事务
那样可以作用到代码块级别。

24.说说spring的事务传播行为?

spring事务的传播行为
说的是当一个方法调用另一个方法时,
事务该如何操作。
1.PROPAGATION_REQUIRED:
如果当前没有事务,
就创建一个新事务,
如果当前存在事务,
就加入该事务,
该设置是最常用的设置。

2.PROPAGATION_SUPPORTS:
支持当前事务,
如果当前存在事务,
就加入该事务,
如果当前不存在事务,
就以非事务执行。‘

3.PROPAGATION_MANDATORY:
支持当前事务,
如果当前存在事务,
就加入该事务,
如果当前不存在事务,
就抛出异常。

4.PROPAGATION_REQUIRES_NEW:
创建新事务,
无论当前存不存在事务,
都创建新事务。

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

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

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

25.Spring事务的实现方式和实现原理

1.划分处理单元——IOC:
由于spring解决的问题是
对单个数据库进行局部事务处理的,
具体的实现首相用spring中的IOC
划分了事务处理单元。
并且将对事务的各种配置
放到了ioc容器中
设置事务管理器,
设置事务的传播特性及隔离机制。

2.AOP拦截需要进行事务处理的类:

Spring事务处理模块
是通过AOP功能来实现声明式事务处理的,
具体操作
比如事务实行的配置和读取,
事务对象的抽象,
用TransactionProxyFactoryBean接口
来使用AOP功能,
生成proxy代理对象,
通过TransactionInterceptor完成
对代理方法的拦截,
将事务处理的功能
编织到拦截的方法中。 

读取ioc容器事务配置属性,
转化为spring事务处理
需要的内部数据结构
TransactionAttributeSourceAdvisor
转化为TransactionAttribute表示的数据对象。 

3.对事物处理实现
事务的生成、提交、回滚、挂起:

spring委托给具体的事务处理器实现。
实现了一个抽象和适配。
适配的具体事务处理器:
DataSource数据源支持、
hibernate数据源事务处理支持、
JDO数据源事务处理支持,
JPA、JTA数据源事务处理支持。
这些支持都是通过设计PlatformTransactionManager、
AbstractPlatforTransaction
一系列事务处理的支持。
为常用数据源支持提供了
一系列的TransactionManager。

结合:
PlatformTransactionManager实现了
TransactionInterception接口,
让其与TransactionProxyFactoryBean结合起来,
形成一个Spring声明式事务处理的设计体系。

26.Spring AOP是什么?

AOP:面向切面编程
AOP技术利用一种称为“横切”的技术,
解剖封装的对象内部,
并将那些影响了多个类的公共行为
封装到一个可重用模块,
这样就能减少系统的重复代码,
降低模块间的耦合度,
并有利于未来的可操作性和可维护性。
AOP把软件系统分为两个部分:
核心关注点
和横切关注点。
业务处理的主要流程是核心关注点,
与之关系不大的部分是横切关注点。
横切关注点的一个特点是,
他们经常发生在核心关注点的多处,
而各处都基本相似。
比如权限认证、日志、事务处理。

27.说说AOP实现原理

AOP:
这里的AOP指的是面向切面编程思想,
而不是Spring AOP
主要的的实现技术主要有
Spring AOP和AspectJ。
1、AspectJ的底层技术。
 AspectJ的底层技术是静态代理,
即用一种AspectJ支持的特定语言编写切面,
通过一个命令来编译,
生成一个新的代理类,
该代理类增强了业务类,
这是在编译时增强,
相对于下面说的运行时增强,
编译时增强的性能更好。

Spring AOP

Spring AOP采用的是动态代理,
在运行期间对业务方法进行增强,
所以不会生成新类,
对于动态代理技术,
Spring AOP提供了对
JDK动态代理的支持以及CGLib的支持。

JDK动态代理只能为接口创建动态代理实例,
而不能对类创建动态代理。
需要获得被目标类的接口信息(应用Java的反射技术),
生成一个实现了代理接口的动态代理类(字节码),
再通过反射机制获得动态代理类的构造函数,
利用构造函数生成动态代理类的实例对象,
在调用具体方法前调用invokeHandler方法来处理。

CGLib动态代理需要依赖asm包,
把被代理对象类的class文件加载进来,
修改其字节码生成子类。

但是Spring AOP基于注解配置的情况下,
需要依赖于AspectJ包的标准注解,
但是不需要额外的编译以及AspectJ的织入器,
而基于XML配置不需要。

28.请描述JDK动态代理和CGLI代理的区别?

1.JDK动态代理
此时代理对象和目标对象实现了相同的接口,
目标对象作为代理对象的一个属性,
具体接口实现中,
可以在调用目标对象相应方法前后
加上其他业务处理逻辑。

代理模式在实际使用时
需要指定具体的目标对象,
如果为每个类都添加一个代理类的话,
会导致类很多,
同时如果不知道具体类的话,
怎样实现代理模式呢?
这就引出动态代理。
JDK动态代理只能
针对实现了接口的类生成代理。

2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)
代理是针对类实现代理,
主要是对指定的类生成一个子类,
覆盖其中的所有方法,
所以该类或方法不能声明称final的。

如果目标对象没有实现接口,
则默认会采用CGLIB代理;

如果目标对象实现了接口,
可以强制使用CGLIB实现代理
添加CGLIB库,
并在spring配置中加入
<aop:aspectj-autoproxy proxy-target-class="true"/>)

29.怎样用注解的方式配置Spring?

Spring在2.5版本以后
开始支持用注解的方式来配置依赖注入。
可以用注解的方式
来替代XML方式的bean描述,
可以将bean描述转移到组件类的内部,
只需要在相关类上、
方法上或者字段声明上使用注解即可。
注解注入将会被容器在XML注入之前被处理,
所以后者会覆盖掉前者
对于同一个属性的处理结果。
注解装配在Spring中是默认关闭的。
所以需要在Spring文件中
配置一下才能使用基于注解的装配模式。
如果你想要在你的应用程序中
使用关于注解的方法的话,
参考如下的配置。
<beans>
   <context:annotation-config/>
</beans>
在 <context:annotation-config/>
标签配置完成以后,
就可以用注解的方式在Spring中向属性、
方法和构造方法中自动装配变量。

下面是几种比较重要的注解类型:
@Required:该注解应用于设值方法。

@Autowired:该注解应用于有值设值方法、
非设值方法、
构造方法和变量。
@Qualifier:该注解和@Autowired注解搭配使用,
用于消除特定bean自动装配的歧义。
JSR-250 Annotations:
Spring支持基于JSR-250 
注解的以下注解,
@Resource、
@PostConstruct 
和 @PreDestroy。

30.如何在Spring中注入一个Java Collection?

•   <list> :   
该标签用来装配可重复的list值。
 <!-- java.util.List -->
      <property name="customList">
        <list>
           <value>INDIA</value>
           <value>Pakistan</value>
           <value>USA</value>
           <value>UK</value>
        </list>
      </property>

•   <set> :   
 该标签用来装配没有重复的set值。
     <!-- java.util.Set -->
     <property name="customSet">
        <set>
           <value>INDIA</value>
           <value>Pakistan</value>
           <value>USA</value>
           <value>UK</value>
        </set>
      </property>


•   <map>:  
 该标签可用来注入键和值可以为任何类型的键值对。
    <!-- java.util.Map -->
     <property name="customMap">
        <map>
           <entry key="1" value="INDIA"/>
           <entry key="2" value="Pakistan"/>
           <entry key="3" value="USA"/>
           <entry key="4" value="UK"/>
        </map>
      </property>


•   <props> : 
该标签支持注入键和值都是字符串类型的键值对。
      <!-- java.util.Properties -->
    <property name="customProperies">
        <props>
            <prop key="admin">admin@nospam.com</prop>
            <prop key="support">support@nospam.com</prop>
        </props>
    </property>

原文发布于微信公众号 - JAVA高级架构(gaojijiagou)

原文发表时间:2018-11-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术墨客

Hazelcast集群服务(1)——Hazelcast介绍

    “分布式”、“集群服务”、“网格式内存数据”、“分布式缓存“、“弹性可伸缩服务”——这些牛逼闪闪的名词拿到哪都是ITer装逼的不二之选。在Javaer的...

2893
来自专栏java学习

你竟敢说你懂Spring框架?有可能你是没看到这些...(上)

所以,特地去搜刮了一些关于spring的面试题,希望能帮助各位同学在升职加薪的路上,一去不复返。

1102
来自专栏程序员宝库

给你一份详细的 Spring Boot 知识清单

在过去两三年的Spring生态圈,最让人兴奋的莫过于Spring Boot框架。或许从命名上就能看出这个框架的设计初衷:快速的启动Spring应用。因而Spri...

1085
来自专栏阿杜的世界

聊聊单元测试

单元测试(unit testing):是指对软件中的最小可测试单元进行检查和验证。

1001
来自专栏编程之旅

Linux的用户管理(二)

上次的博客我们讲了关于Linux的用户管理的内容,现在我们来讲第二部分——系统用户组的管理。

1141
来自专栏JMCui

Netty 系列一(核心组件和实例).

    早期的 Java API 只支持由本地系统套接字库提供所谓的阻塞函数来支持网络编程。由于是阻塞 I/O ,要管理多个并发客户端,需要为每个新的客户端So...

983
来自专栏小灰灰

熔断Hystrix使用尝鲜

熔断Hystrix使用尝鲜 当服务有较多外部依赖时,如果其中某个服务的不可用,导致整个集群会受到影响(比如超时,导致大量的请求被阻塞,从而导致外部请求无法进来)...

3449
来自专栏Java技术栈

给你一份超详细 Spring Boot 知识清单

在过去两三年的Spring生态圈,最让人兴奋的莫过于Spring Boot框架。或许从命名上就能看出这个框架的设计初衷:快速的启动Spring应用。因而Spri...

1072
来自专栏Java架构

spring思维导图,让spring更加简单易懂

2154
来自专栏云霄雨霁

Java虚拟机--(互斥同步与非阻塞同步)和锁优化

1944

扫码关注云+社区