SSM 高级面试题

1. Spring 依赖注入方式有那些?

参考答案

    通过构造器注入
    通过 setter 注入
    通过 filed 注入

2. Spring Boot 特点有哪些?

参考答案

    Spring Boot 的特点:
    (1)快速开发 Spring 应用的框架
    (2)内嵌 Tomcat 和 Jetty 容器,不需要单独安装容器,jar 包直接发布一个 Web 应用
    (3)简化 Maven 配置,继承父工程这种方式,一站式引入需要的各种依赖
    (4)基于注解的零配置思想
    (5)和各种流行框架 Spring MVC、Mybatis、Spring Cloud 无缝整合

3. Spring Boot 常用注解有哪些?

参考答案

    @SpringBootApplication:这个注解是 Spring Boot 最核心的注解,用在 Spring Boot 的主类上,标识这是一个 Spring Boot 应用,用来开启 Spring Boot 的各项能力。相关等同于@Configuration,@EnableAutoConfiguration 和@ComponentScan 三个注解同时使用。
    @EnableAutoConfiguration:Spring Boot 自动配置开启注解。
    @ConditionalOnXXXX:Spring Boot 基于@Conditional 扩展出的衍生注解,根据是否满足某一个特定条件来决定是否加载指定的 Bean。比如扩展出的注解有:@ConditionalOnBean、@ConditionalOnClass 等。
    @ConfigurationProperties:基于类型安全的属性配置注入,可以将 properties 属性和一个 Bean 及其属性关联,从而实现类型安全配置。

4. AOP 有哪些使用场景?

参考答案

    场景一: 记录日志
    场景二: 监控方法运行时间 (监控性能)
    场景三: 权限控制
    场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
    场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )

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

参考答案

    1. 拦截器基于 java 的反射机制,而过滤器是基于函数回调
    2.  拦截器不依赖于 servlet 容器,过滤器依赖 servlet 容器
    3.  拦截器只能对 action 请求起作用,而过滤器则可以对几乎所有的请求起作用
    4.  在 action 的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
    5.  拦截器可以获取 IOC 容器中的各个 bean,而过滤器就不行,这点很重要,在拦截器注入一个 service,可以调用业务逻辑

6. Git 和 Svn 区别?

参考答案

    Svn 是集中式的版本控制系统。可以看出 Svn 集中式版本控制都是把所有的版本存储在 Svn 服务器中且必须要联网到 Svn 服务器才可以进行版本的回退、更新等操作。
    假如哪天 Svn 服务器坏了,那么所有的版本代码都将丢失,也就无法获取代码和回退版本等操作。
    Git 是分布式版本控制系统。使用 Git 每个电脑都有完整的版本号和日志信息。且没有网的时候,Git 照样可以工作,只是把代码提交到本地,待有网在提交到远程 Git 仓库。就算哪天 Git 服务器坏了也没事,因为本地仓库都保存了完整的版本。

其他收集:


何为Spring Bean容器?Spring Bean容器与Spring IOC容器有什么不同吗?★★★
答:用于创建Bean对象,管理Bean对象的容器,Spring IOC容器本质上指的就是Spring Bean容器,Spring Bean容器中最核心的机制是IOC机制(控制反转),所以有时候又将Spring Bean容器称之为Spring IOC容器。

Spring IOC如何理解?★★★
答:IOC是Spring中提供一种控制反转机制,目的是将我们项目中对象的依赖管理交给Spring实现,这样可以更好实现对象关系的解耦,提高程序的可扩展性。

Spring DI如何理解?★★★
答:DI是Spring中的依赖注入机制,IOC的实现需要借助这种机制,我们通常会这样理解,Spring Bean容器中的IOC思想是一种目标,而DI是实现这种思想目标的手段。

Spring中基于注解如何配置对象的作用域?以及如何配置延迟加载机制?★
答:@Scope(“singleton”)

@Scope(“prototype”)

@Lazy(value=true)

Spring工厂底层构建Bean对象借助什么机制?当对象不使用时要释放资源,目的是什么?何为内存泄漏?★★★★
答:借助反射机制,目的是防止内存泄漏;对象已经不使用了但还占用着内存,这种现象称之为内存泄漏,内存泄漏不是内存溢出,但是它是内存溢出的一个导火索,内存溢出可直接导致系统崩溃。

描述Spring MVC处理流程以及应用优势。★★★★
客户端发出一个HTTP请求给WEB服务器,WEB服务器对HTTP请求进行解析,如果匹配前端控制器(Dispatcher Servlet)的请求映射路径,WEB容器将请求转交给Dispatcher Servlet。
Dispatcher Servlet接收到这个请求之后将根据请求的信息以及处理器映射器(Handler Mapping)的配置找到处理请求的处理器(Handler)。
由具体的处理器适配器(Handler Adapter)对Handler进行具体的调用。
Handler对数据处理完成后将返回一个ModelAndView对象给Dispatcher Servlet。
Dispatcher Servlet通过视图解析器(ViewResolver)将ModelAndView转化为真正的视图View。
Dispatcher Servlet通过Model解析出ModelAndView中的参数进行解析,最终展现出完整的View并返回给客户端。
Spring中的事务处理方式以及优缺点。★★★★
答:优点在于:

1:能够实现全局事务的控制,通过EJB、CMT进行事物的管理。

2:能够保证项目模块在系统中完成的功能是可控制的操作(AOP)。

缺点在于:

1:Spring中的事物声明有编程式事物和申明是事物。

MyBatis应用中#与$有什么异同点?★★
相同点:都是通过get来获取值。

不同点:$传进去的字符串不带引号,#号带引号。

MyBatis应用动态SQL解决了什么问题?★★★
答:有时候固定的SQL语句不能满足我们的应用需求,这个时候需要在此基础上建立动态的查询语句。

MyBatis提供了多种注解,可以提供动态查询语言。

比如说在开发的时候,遇到这样的场景:界面提供了多种查询,但是都是非必填写,在选择查询条件时可以选中任意几种组合作为查询条件,如果在使用JDBC的时候,需要判断参数为空,自己组装SQL,但MyBatis提供动态SQL机制,避免了此类问题。

Shiro框架权限管理时的认证和授权流程描述。★★★
答:Shiro权限控制流程:

应用代码→调用Subject(Shiro的Subject代表当前登录的用户)控制权限→Subject在Shiro框架内部调用SecurityManager安全管理器→安全管理器调用Realm(程序和安全数据连接器)。

Subject要进行任何操作,都必须要调用安全管理器(对我们来说是自动的),而安全管理器会调用指定的Realms对象,来连接安全数据。

Realms用来编写安全代码逻辑和访问安全数据,是连接程序和安全数据的桥梁。

BeanFactory和ApplicationContext有什么区别?★★
答:BeanFactory可以理解为含有Bean集合的工厂类,BeanFactory包含了Bean的定义信息,以便在接收到客户端请求时将对应的Bean实例化。

BeanFactory还能在实例化对象的时候生成协作类之间的关系,此举将Bean自身与Bean客户端的配置中解放出来,BeanFactory还包含了Bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

从表面上看,ApplicationContext如同BeanFactory一样具有Bean定义、Bean关联关系的设置,根据请求分发Bean的功能,但ApplicationContext在此基础上还提供了其他的功能。

请解释Spring Bean的生命周期。★★★
答:SpringBean的生命周期简单易懂,在一个Bean实例被初始化时,需要执行一系列的初始化操作,以达到可用状态。同样的,当一个Bean不在被调用时需要进行相关的解析操作,并从Bean容器中移除。

Spring Bean Factory负责管理在Spring容器中被创建的Bean的生命周期,Bean的生命周期由两组回调(Call back)方法组成。

初始化之后调用的回调方法和销毁之前调用的回调方法。

Spring框架提供了以下四种方式来管理Bean的生命周期:

InitializingBean和DisposableBean回调接口
针对特殊行为的其他Aware接口

Bean配置文件中的Custom init()方法和destroy()方法

@PostConstruct和@PreDestroy注解方式

//使用customInit()和 customDestroy()方法管理bean生命周期的代码样例如下

<beans>

<bean id="demoBean" class="com.howtodoinjava.task.DemoBean"

       init-method="customInit" destroy-method="customDestroy"></bean>

</beans>

Spring Bean的作用域之间有什么区别?★★
答:Spring容器中的Bean可以分为5个范围,所有范围的名称都是有说明的,但是为了避免混淆,还是让我们来解释一下。

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

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

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

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

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

全局作用域与Servlet中的session作用域效果相同。

在Spring AOP中,关注点和横切关注的区别是什么?★★
答:关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用;比如日志,安全和数据传输,几乎应用的每个模块都需要的功能,因此这些都属于横切关注点。

使用Spring框架的好处是什么?★★★★
答:轻量:Spring是轻量的,基本的版本约2MB。

控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

面向切面编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

容器:Spring包含并管理应用中对象的生命周期和配置。

MVC框架:Spring的WEB框架是一个精心设计的框架,是WEB框架的一个很好的替代品。

事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

异常处理:Spring提供方便的API把具体技术相关的异常(比如JDBC,Hibernate or JDO抛出的)转化为一致的unchecked异常。

Spring中用到了哪些设计模式?★★★★★
答:Spring框架中使用到了大量的设计模式,下面列举了比较有代表性的:

代理模式:在AOP和remoting中被用的比较多。

单例模式:在Spring配置文件中定义的Bean默认为单例模式。

模板方法:用来解决代码重复的问题,比如:RestTemplate、JmsTemplate、JpaTemplate。

工厂模式:BeanFactory用来创建对象的实例。

适配器:Spring AOP。

装饰器:Spring Data hashmapper。

观察者:Spring时间驱动模型。

回调:Spring ResourceLoaderAware回调接口。

Spring如何保证Controller并发安全问题?★★
Spring多线程请求过来调用的Controller对象都是一个,而不是一个请求过来就创建一个Controller对象。

并发安全?原因就在于Controller对象是单例的,那么如果不小心在类中定义了类变量,那么这个类变量是被所有请求共享的,这可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常。

那有没有办法让Controller不以单例而以每次请求都重新创建的形式存在呢?

答案是当然可以,只需要在类上添加注解@Scope(“prototype”)即可,这样每次请求调用的类都是重新生成的(每次生成会影响效率)。

虽然这样可以解决问题,但增加了时间成本,总让人不爽,还有其他方法吗?答案是肯定的!

使用ThreadLocal来保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来。

使用Spring框架的好处是什么?★★★★(重复)
答:轻量:Spring是轻量的,基本的版本约2MB。

控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。

面向切面编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。

容器:Spring包含并管理应用中对象的生命周期和配置。

MVC框架:Spring的WEB框架是一个精心设计的框架,是WEB框架的一个很好的替代品。

事务管理:Spring提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。

异常处理:Spring提供方便的API把具体技术相关的异常(比如JDBC,Hibernate or JDO抛出的)转化为一致的unchecked异常。

在Spring中如何注入一个Java集合?★★
答:Spring提供以下几种集合的配置元素:

<list>类型用于注入一列值,允许有相同的值。

<set>类型用于注入一组值,不允许有相同的值。

<map>类型用于注入一组键值对,键和值都可以为任意类型。

<props>类型用于注入一组键值对,键和值都只能为String类型。

Spring支持的事务管理类型。★★★
答:Spring支持如下两种方式的事务管理

编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。

声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离。你只需要通过注解或者XML配置管理事务。

Spring框架的事务管理有哪些优点?★★★
答:Spring为不同的事务API(如JTA、JDBC、Hibernate、JPA和JDO)提供了统一的编程模型。

Spring为编程式事务管理提供了一个简单的API而非一系列复杂的事务API(如JTA)。

Spring支持声明式事务管理。

Spring事务管理可以和多种数据访问技术很好的融合。

Spring MVC的主要组件有哪些?★★★★★
答:前端控制器DispatcherServlet(不需要程序员开发)

作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet就减少了其他组件之间的耦合度。

处理器映射器HandlerMapping(不需要程序员开发)

作用:根据请求的URL来查找Handler。

处理器适配器HandlerAdapter

注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。

处理器Handler(需要程序员开发)

视图解析器ViewResolver(不需要程序员开发)

作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)

视图View(需要程序员开发jsp)

View是一个接口,它的实现类支持不同的视图类型(jsp、freemarker、pdf等)

Spring MVC怎么和AJAX项目调用?★★★★
答:通过Jackson框架就可以把Java里面的对象直接转化成JS可以识别的Json对象,具体步骤如下:

加入Jackson.jar

在配置文件中配置Json的映射

在接受Ajax方法里面可以直接返回Object、List等,但方法前面要加上。

MyBatis中#和$的区别?★(重复)
#{}是预编译处理,${}是字符串替换;

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理${}时,就是把${}替换成变量的值,相当于字符串拼接;

使用#{}可以有效的防止SQL注入,提高系统安全性。

MyBatis的缓存机制,一级、二级分别解释一下。★★★★★
答:一级缓存:

默认开启;

SqlSession级别的缓存,实现在同一个会话中数据的共享;

一级缓存的生命周期和SqlSession一致;

当有多个SqlSession或者分布式环境下,数据库与操作会引起脏读。

二级缓存:

默认不开启,需要手动开启;

SqlSessionFactory级别的缓存,实现不同会话中数据的共享,是一个全局变量;

可自定义存储源,如Ehcache;

当开启缓存后,数据查询的执行流程是:二级缓存→一级缓存→数据库;

不同于一级缓存,二级缓存可设置是否允许刷新和刷新频率实现;

实体类实现序列化,在mapper文件中开启<cache>;

在配置文件中设置cacheEnabled为true。

Spring MVC与Struts2的区别?★★
答:SpringMVC的入口是一个Servlet,即前端控制器,而Struts2入口是一个Filter过滤器;

SpringMVC是基于方法开发,传递参数是通过方法形参,可以设计为单例或多例(建议单例),Struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

MyBatis的基本工作流程。★★★★★
答:One:读取配置文件,配置文件包含数据库连接信息和Mapper映射文件或者Mapper包路径。

Two:有了这些信息就能创建SqlSessionFactory,SqlSessionFactory的生命周期是程序级,程序运行时建立,程序结束时消亡。

Three:SqlSessionFactory建立SqlSession,目的是执行SQL语句,SqlSession是过程级,一个方法中建立,方法结束应该关闭。

Four:当用户使用mapper.xml文件中配置的方法时,MyBatis首先会解析SQL动态标签为对应数据库SQL语句的形式,并将其封装进MapperStatement对象,然后通过Executor将SQL注入数据库执行,并返回结果。

Five:将返回的结果通过映射,包装成Java对象。

什么是MyBatis的接口绑定,有什么好处?★★★
答:接口映射就是在MyBatis中任意定义接口,然后把接口里的方法和SQL语句绑定,我们通过直接调用接口方法,例如:

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

//这样比原来SqlSession提供的方法,例如:

List<Country> countryList = sqlSession.selectList(“selectAll”);

//我们可以有更加灵活的选择和设置

注意:One:Mapper.xml文件的namespace属性必须配置为接口的全限定名称,接口中方法与Mapper.xml中的<select><insert>id值必须相同,且接口方法的返回值类型必须与Mapper.xml配置的resultType一致,这里后者起到决定作用;

Two:select查询通过在Mapper.xml中配置ResultMap标签,将查询结果的列名与字段名对应,insert语句通过#{属性名}从接口参数获取值放到SQL语句中。

Three:Mapper.xml接口绑定本质是动态代理。

MyBatis的编程步骤。★★★★
答:One:创建SqlSessionFactory;

Two:通过SqlSessionFactory创建SqlSession;

Three:通过SqlSession执行数据库操作;

Four:通过session.commit()提交事务;

Five:session.close()关闭事务。

JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?★★★★
答:JDBC编程的不足之处:

One:数据库链接创建、释放频繁会造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题;

Two:SQL语句在写代码中造成代码不易维护,实际应用SQL变化的可能较大,SQL变动需要改变Java代码;

Three:向SQL语句传递参数麻烦,因为SQL语句的where条件不一样,可能多也可能少,占位符需要和参数一一对应;

Four:对结果集解析麻烦,SQL变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成POJO对象解析比较方便。

MyBatis的解决方案

One:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库连接;

Two:将SQL语句配置在xxxmapper.xml文件中与Java代码分离;

Three:MyBatis自动将Java对象映射至SQL语句;

Four:MyBatis自动将SQL执行结果映射至Java对象。

简述MyBatis的优缺点?★★★★
答:优点

One:易于上手和掌握;

Two:SQL写在xml里面,便于统一管理和优化;

Three:减少SQL与程序代码的耦合;

Four:提供xml标签,支持动态SQL编写;

缺点

One:SQL工作量大,尤其是字段多,关联表多时更加;

Two:SQL依赖于数据库,导致数据库移植性差;

Three:由于xml里面标签id必须唯一,导致DAO中方法不支持重装,所以DAO层必须是接口。

使用MyBatis的mapper接口调用时有哪些要求?★★★
答:One:Mapper接口方法名和Mapper.xml中定义的每个SQL的id相同;

Two:Mapper接口方法的输入参数类型和Mapper.xml中定义的每个SQL的parameterType的类型相同;

Three:Mapper接口方法的输出参数类型和Mapper.xml中定义的每个SQL的resultType的类型相同;

Four:Mapper.xml文件中的namespace即是Mapper接口的类路径。

谈谈你对Spring MVC的理解。★★★
答:One:是一个基于MVC的WEB框架;

Two:SpringMVC是Spring的一个模块,是Spring的子容器,子容器可以拿父容器的东西,但是父容器不能拿子容器的东西;

Three:SpringMVC的前端控制器DispatcherServlet,用于分发请求,使开发变得简单;

Four:SpringMVC流程以及SpringMVC三大组件

HandlerMapping:处理器映射器,用户请求路径到Controller方法的映射;
HandlerAdapter:处理器适配器,根据Handler(Controller类)的开发方式(注解开发/其他开发)方式的不同去寻找不同的处理器适配器。
ViewResolver:视图解析器,可以解析JSP、freemarkerr、pdf等。
简述MyBatis的插件运行原理,以及如何编写一个插件?★★
答:1)MyBatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,MyBatis通过动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

2)实现MyBatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。

MyBatis动态SQL是做什么的?都有哪些动态SQL?请简述一下动态SQL的执行原理。★★★
答:1)MyBatis动态SQL可以让我们在XML映射文件内,以标签的形式编写动态SQL,完成逻辑判断和动态拼接SQL的功能。

MyBatis提供了9种动态SQL标签:trim\where\set\foreach\if\choose\when\otherwise\bind。
其执行原理为,使用OGNL从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。
MyBatis是否支持延迟加载?如果支持,它的实现原理是什么?★★
答:1):MyBatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在MyBatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true\false。

2)它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的SQL,把B查询出来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用,这就是延迟加载的基本原理。

MyBatis能执行一对一、一对多的关联查询吗?都有哪些实现方式?以及它们之间的区别?★★
答:能,MyBatis不仅仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的关联查询;多对一查询,其实就是一对一查询,只需要把selectOne()修改为selectList()即可;多对多查询,其实就是一对多查询,只需要把selectOne()修改为selectList()即可。

关联对象查询,有两种实现方式,一种是单独发送一个SQL去查询关联对象,赋给主对象,然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用join查询,一部分列是A对象的属性值,另外一部分列是关联对象B的属性值,好处是只发一个SQL查询,就可以把主对象和其关联对象查出来。

MyBatis是如何将SQL执行结果封装为目标对象并返回的?都有哪些映射形式?★★
答:第1种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系。

第2种是使用SQL列的别名功能,将列别名书写为对象属性名,比如T_NAME AS NAME,对象属性名一般是name,小写,但是列名布区分大小写,MyBatis会忽略列名大小写,智能找到与之对应对象属性名,你甚至可以写成T_NAME AS NaMe,MyBatis一样可以正常工作。

MyBatis映射文件中,如果A标签通过include引用了B标签的内容,请问B标签能否定义在A标签的后面?还是说必须定义在A标签的前面?★★★
答:虽然MyBatis解析XML映射文件是按照顺序解析的,但是被引用的B标签依然可以定义在任何地方,MyBatis都可以正确识别;原理是MyBatis解析A标签,发现A标签引用了B标签,但是B标签尚未解析到,尚不存在,此时MyBatis会将A标签标记为为解析状态,然后继续解析余下的标签,包含B标签,待所有标签解析完毕,MyBatis会重新解析那些被标记为未解析的标签,此时再解析A标签时,B标签已经存在,A标签也就可以正常解析完成了。

MyBatis里面的动态SQL是怎么设定的?用什么语法?★★
答:MyBatis里的动态SQL一般是通过if节点来实现,通过OGNL语法来实现,但是如果要写得完整,必须配合where、trim节点,where节点是判断包含节点有内容就插入where,否则不插入;trim节点是用来判断如果动态语句是以and或or开始,那么会自动把这个and或者or去掉。

MyBatis都有哪些Executor执行器?它们之间的区别是什么?★★★
答:MyBatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

ReuseExecutor:执行update或select,以SQL作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String,Statement>内,供下一次使用,简言之,就是重复使用的Statement对象。

BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有SQL都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理,与JDBC批处理相同。

作用范围:Executor的这些特点,都严格限制再SqlSession生命周期范围内。

为什么说MyBatis是半自动ORM映射工具?它与全自动的区别在那里?★★★
答:Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而MyBatis在查询关联对象或关联集合对象时,需要手动编写SQL来完成,所以称之为半自动ORM映射工具。

心得:面试题看似很简单,但是想要能正确回答上来,必定是研究过源码且深入的人,而不是仅会使用的人,或者用得很熟的人。

简单介绍一下你对MyBatis的理解。★★★★★
答:1)MyBatis配置;

SqlMapConfig.xml,此文件作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息;
Mapper.xml文件即sql映射文件,文件中配置了操作数据库的SQL语句,此文件需要在SqlMapConfig.xml中加载;
通过MyBatis环境等配置信息构造SqlSessionFactory会话工厂对象;
由会话工厂对象创建sqlSession即会话对象,操作数据库需要通过sqlSession进行;
MyBatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器,一个是缓存执行器;
Mapped Statement也是MyBatis一个底层封装对象,它包装了MyBatis配置信息及SQL映射信息等;mapper.xml文件中一个sql对应一个Mapped Statement对象,SQL的id即是Mapped Statement的id。
Mapped Statement对SQL执行输入参数进行定义,包括HashMap、基本类型、POJO、Executor通过Mapped Statement在执行SQL前将输入的Java对象映射至SQL中,输入参数映射就是JDBC编程中对preparedStatement设置参数。
Mapped Statement对SQL执行输出结果进行定义,包括HashMap、基本类型、POJO、Executor通过Mapped Statement在执行SQL后将输出结果映射至Java对象中,输出结果映射过程相当于JDBC编程中对结果集的解析处理过程。
介绍一下Spring的事务管理。★★★★
答:事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作,这样可以防止出现脏数据,防止数据库数据出现问题。

开发中为了避免这种情况一般都会进行事务管理,Spring中也有自己的事务管理机制,一般是使用TransactionManager进行管理,可以通过Spring的注入来完成此功能。

Spring支持如下两种方式的事务管理:

编程式事务管理:这意味着你可以通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
声明式事务管理:这种方式意味着你可以将事务管理和业务代码分离,你只需要通过注解或者XML配置管理事务。
注意:一般选择声明式事务管理,因为这种方式和应用程序的关联较少。

简述SSM优缺点以及使用场景。(题目不对:MyBatis和Hibernate对比。)★★★
答:1)MyBatis和Hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写SQL语句,不过MyBatis可以通过XML或注解方式灵活配置要运行的SQL语句,并将Java对象和SQL语句映射生成最终执行的SQL,最后将SQL执行的结果再映射生成Java对象。

2)MyBatis学习门槛低,简单易学,程序员直接编写原生态SQL,可严格控制SQL执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是MyBatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套SQL映射文件,工作量大。

Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需要固定的定制化软件)如果用Hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。
简述SpringMVC的工作流程。★★★★★(重复)
答:

用户发送请求至前端控制器DispatcherServlet;
DispatcherServlet收到请求调用HandlerMapping处理器映射器;
HandlerMapping根据请求URL找到具体的处理器,生成处理器对象以及处理器拦截器(如果有则 生成)一并返回给DispatcherServlet;
DispatcherServlet通过HandlerAdapter处理器适配器调用处理器;
执行处理器(Controller,也叫后端控制器);
Controller执行完成返回ModelAndView;
HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet;
DispatcherServlet将ModelAndView传给ViewReslover视图解析器;
ViewReslover解析后返回具体View;
DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中);
DispatcherServlet响应用户。
如果你用过Struts2,请简述Spring MVC和Struts2的区别有哪些?★★
答:SpringMVC的入口是一个Servlet即前端控制器,而Struts2入口是一个Filter过滤器。

SpringMVC是基于方法开发(一个URL对于一个方法),请求参数传递到方法的形参,可以设计为单例或多例模式(建议单例),Struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,SpringMVC通过参数解析器是将Request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过Request域传输到页面,JSP视图解析器默认使用JSTL。

怎么把数据放入Session里面?★★★
答:可以声明一个Request或者Session先拿到Session,然后就可以放入数据,或者可以在类上面加上@SessionAttributes注解,里面包含的字符串就是要放入Session里的key。

简述Spring MVC的执行流程。(重复)
MyBatis的好处是什么?★★★★
答:1)MyBatis把SQL语句从Java源程序中独立出来,放在单独的XML文件中编写,给程序的维护带来了很大便利。

MyBatis封装了底层JDBC API的调用细节,并能自动将结果集转换成JavaBean对象,大大简化了Java数据库编程的重复工作。
MyBatis需要程序员自己编写SQL语句,程序员可以结合数据库自身的特点,灵活控制SQL语句,因此能够实现比Hibernate等全自动ORM框架更高的查询效率,能够完成复杂查询。
Bean工厂和Application contexts有什么区别?★★
答:Application Contexts提供一种方法处理文本消息,一个通常的做法是加载文件资源(比如镜像),它们可以向注册为监听器的Bean发布事件。另外,在容器或容器内的对象上执行的那些不得不由Bean工厂以程序化方式处理的操作,可以在Application Contexts中以声明的方式处理。

Application Contexts实现了Message Source接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。

解释Spring支持的几种Bean的作用域。★★★
答:Spring框架支持以下五种Bean的作用域

Singleton:Bean在每个SpringIOC容器中只有一个实例;
Prototype:一个Bean的定义可以有多个实例;
Request:每次HTTP请求都会创建一个Bean,该作用域仅在基于WEB的Spring Application Context情形下有效;
Session:在一个HTTP Session中,一个Bean定义对应一个实例,该作用域仅在基于WEB的Spring Application Context情形下有效;
Global-Session:在一个全局的HTTP Session中,一个Bean定义对应一个实例,该作用域仅在基于WEB的Spring Application Context情形下有效;
缺省的Spring Bean的作用域是Singleton。
什么是Bean的自动装配?★★
答:Spring容器能够自动装配相互合作的Bean,这意味着容器不需要<constructor-arg>和<property>,能通过Bean工厂自动处理Bean之间的协作。

什么是基于Java的Spring注解配置?给一些注解的例子。★★
答:基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。

以@Configuration注解为例,它用来标记类可以当作一个Bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个Bean注册进Spring应用上下文。

Spring通过什么方式访问Hibernate?★
答:在Spring中有两种方式访问Hibernate:

控制反转Hibernate Template和Callback;
继承Hibernate DAO Support提供一个AOP拦截器。
如何通过HibernateDaoSupport将Spring和Hibernate结合起来?★
答:用Spring的Session Factory调用LocalSessionFactory,集成过程分为三步:

配置the Hibernate SessionFactory;
继承HibernateDaoSupport实现一个DAO;
在AOP支持的事务中装配。
Spring框架的事务管理有哪些优点?★★★
答:1)Spring为不同的事务API如JTA、JDBC、Hibernate、JPA和JDO,提供一个不变的编程模式;

2)Spring为编程式事务管理提供了一套简单的API而不是一些复杂的事务API;

Spring支持声明式事务管理;
Spring事务管理和Spring各种数据访问抽象层很好的集成。
在Spring AOP中,关注点和横切关注的区别是什么?★
答:关注点是应用中的一个模块的行为,一个关注点可能被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用;比如日志,安全和数据传输,几乎应用的每个模块都需要的功能,因此这些都属于横切关注点。

AOP作用是什么?底层如何实现?在哪些地方会用到?分别简述切面、切入点、和通知。★★★★
答:AOP表示面向切面编程,将一个系统中共同的业务逻辑提取出来,进行单独封装成一个组件(切面),然后以配置的方式作用于系统中,实现程序的可插拔性,提高代码的复用性,提升系统的灵活性和性能。

底层实现:JDK动态代理,只支持接口注入,CGLIB:可以支持普通类的注入。

哪些地方会用到?事务开启,日志记录,安全验证,权限管理。

切面:系统中共通的业务提取出来,在某个时刻或者某个阶段共同调用。

切入点:找到目标方法,给它追加共通的业务逻辑,在Spring中提供了切入点表达式帮助我们找到目标方法execution。

通知:什么时候调用这个共通的业务逻辑,用于指定切面方法作用到系统中的时机,前置通知、后置通知、环绕通知、异常通知、最终通知。

Spring中AutoWired和Resource之间区别是什么?★★
答:AutoWried:按照类型进行匹配,Spring框架自带的,查看当前Spring容器中哪个Bean类型和引用类型一致,就进行注入,如果有多个匹配类型就会报错。

Resource:默认按照名称进行注入,如果找不到对应的名称按照Bean类型进行注入。
 

如何实现一个 IOC 容器
1 、配置文件配置包扫描路径
2 、递归包扫描获取 .class 文件
3 、反射、确定需要交给 IOC 管理的类
4 、对需要注入的类进行依赖注入
配置文件中指定需要扫描的包路径
定义一些注解,分别表示访问控制层、业务服务层、数据持久层、依赖注入注解、获取配置文件注
从配置文件中获取需要扫描的包路径,获取到当前路径下的文件信息及文件夹信息,我们将当前路
径下所有以 .class 结尾的文件添加到一个 Set 集合中进行存储
遍历这个 set 集合,获取在类上有指定注解的类,并将其交给 IOC 容器,定义一个安全的 Map 用来
存储这些对象
遍历这个 IOC 容器,获取到每一个类的实例,判断里面是有有依赖其他的类的实例,然后进行递归
注入
spring 是什么?
轻量级的开源的 J2EE 框架。它是一个容器框架,用来装 javabean java 对象),中间层框架(万能胶)
可以起一个连接作用,比如说把 Struts hibernate 粘合在一起运用,可以让我们的企业开发更快、更简
Spring 是一个轻量级的控制反转( IoC) 和面向切面( AOP )的容器框架
-- 从大小与开销两方面而言 Spring 都是轻量级的。
-- 通过控制反转 (IoC) 的技术达到松耦合的目的
-- 提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的
开发
-- 包含并管理应用对象 (Bean) 的配置和生命周期,这个意义上是一个容器。
-- 将简单的组件配置、组合成为复杂的应用,这个意义上是一个框架。
谈谈你对 AOP 的理解
系统是由许多不同的组件所组成的,每一个组件各负责一块特定功能。除了实现自身核心功能之外,这
些组件还经常承担着额外的职责。例如日志、事务管理和安全这样的核心服务经常融入到自身具有核心
业务逻辑的组件中去。这些系统服务经常被称为横切关注点,因为它们会跨越系统的多个组件。
当我们需要为分散的对象引入公共行为的时候, OOP 则显得无能为力。也就是说, OOP 允许你定义从
上到下的关系,但并不适合定义从左到右的关系。例如日志功能。
日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。
OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。
AOP :将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象
(具体业务逻辑)中去。 AOP 可以对某个对象或某些对象的功能进行增强,比如对象中的方法进行增
强,可以在执行某个方法之前额外的做一些事情,在某个方法执行之后额外的做一些事情
BeanFactory ApplicationContext 有什么区别?
ApplicationContext BeanFactory 的子接口
ApplicationContext 提供了更完整的功能:
①继承 MessageSource ,因此支持国际化。
②统一的资源文件访问方式。
③提供在监听器中注册 bean 的事件。
④同时加载多个配置文件。
⑤载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的 web 层。
BeanFactroy 采用的是延迟加载形式来注入 Bean 的,即只有在使用到某个 Bean ( 调用
getBean()) ,才对该 Bean 进行加载实例化。这样,我们就不能发现一些存在的 Spring 的配置问
题。如果 Bean 的某一个属性没有注入, BeanFacotry 加载后,直至第一次使用调用 getBean 方法
才会抛出异常。 ApplicationContext ,它是在容器启动时,一次性创建了所有的 Bean 。这样,在容器启动时,我
们就可以发现 Spring 中存在的配置错误,这样有利于检查所依赖属性是否注入。
ApplicationContext 启动后预载入所有的单实例 Bean ,通过预载入单实例 bean , 确保当你需要的
时候,你就不用等待,因为它们已经创建好了。
相对于基本的 BeanFactory ApplicationContext 唯一的不足是占用内存空间。当应用程序配置
Bean 较多时,程序启动较慢。
BeanFactory 通常以编程的方式被创建, ApplicationContext 还能以声明的方式创建,如使用
ContextLoader
BeanFactory ApplicationContext 都支持 BeanPostProcessor BeanFactoryPostProcessor
使用,但两者之间的区别是: BeanFactory 需要手动注册,而 ApplicationContext 则是自动注册。
描述一下 Spring Bean 的生命周期?
1 、解析类得到 BeanDefinition
2 、如果有多个构造方法,则要推断构造方法
3 、确定好构造方法后,进行实例化得到一个对象
4 、对对象中的加了 @Autowired 注解的属性进行属性填充
5 、回调 Aware 方法,比如 BeanNameAware BeanFactoryAware
6 、调用 BeanPostProcessor 的初始化前的方法
7 、调用初始化方法
8 、调用 BeanPostProcessor 的初始化后的方法,在这里会进行 AOP
9 、如果当前创建的 bean 是单例的则会把 bean 放入单例池
10 、使用 bean
11 Spring 容器关闭时调用 DisposableBean destory() 方法
解释下 Spring 支持的几种 bean 的作用域。
singleton :默认,每个容器中只有一个 bean 的实例,单例的模式由 BeanFactory 自身来维护。该
对象的生命周期是与 Spring IOC 容器一致的(但在第一次被注入时才会创建)。
prototype :为每一个 bean 请求提供一个实例。在每次注入时都会创建一个新的对象
request bean 被定义为在每个 HTTP 请求中创建一个单例对象,也就是说在单个请求中都会复用
这一个单例对象。
session :与 request 范围类似,确保每个 session 中有一个 bean 的实例,在 session 过期后, bean
会随之失效。
application bean 被定义为在 ServletContext 的生命周期中复用一个单例对象。
websocket bean 被定义为在 websocket 的生命周期中复用一个单例对象。 global-session :全局作用域, global-session Portlet 应用相关。当你的应用部署在 Portlet 容器
中工作时,它包含很多 portlet 。如果你想要声明让所有的 portlet 共用全局的存储变量的话,那么
这全局变量需要存储在 global-session 中。全局作用域与 Servlet 中的 session 作用域效果相同。
Spring 框架中的单例 Bean 是线程安全的么?
Spring 中的 Bean 默认是单例模式的,框架并没有对 bean 进行多线程的封装处理。
如果 Bean 是有状态的 那就需要开发人员自己来进行线程安全的保证,最简单的办法就是改变 bean 的作
用域 把 "singleton" 改为 ’‘protopyte’ 这样每次请求 Bean 就相当于是 new Bean() 这样就可以保证线程的
安全了。
有状态就是有数据存储功能
无状态就是不会保存数据 controller service dao 层本身并不是线程安全的,只是如果只
是调用里面的方法,而且多线程调用一个实例的方法,会在内存中复制变量,这是自己的线程的工
作内存,是安全的。
Dao 会操作数据库 Connection Connection 是带有状态的,比如说数据库事务, Spring 的事务管理器
使用 Threadlocal 为不同线程维护了一套独立的 connection 副本,保证线程之间不会互相影响( Spring
是如何保证事务获取同一个 Connection 的)
不要在 bean 中声明任何有状态的实例变量或类变量,如果必须如此,那么就使用 ThreadLocal 把变量变
为线程私有的,如果 bean 的实例变量或类变量需要在多个线程之间共享,那么就只能使用
synchronized lock CAS 等这些实现线程同步的方法了。
Spring 事务的实现方式和原理以及隔离级别?
在使用 Spring 框架时,可以有两种使用事务的方式,一种是编程式的,一种是申明式的,
@Transactional 注解就是申明式的。
首先,事务这个概念是数据库层面的, Spring 只是基于数据库中的事务进行了扩展,以及提供了一些能
让程序员更加方便操作事务的方式。
比如我们可以通过在某个方法上增加 @Transactional 注解,就可以开启事务,这个方法中所有的 sql
会在一个事务中执行,统一成功或失败。
在一个方法上加了 @Transactional 注解后, Spring 会基于这个类生成一个代理对象,会将这个代理对象
作为 bean ,当在使用这个代理对象的方法时,如果这个方法上存在 @Transactional 注解,那么代理逻
辑会先把事务的自动提交设置为 false ,然后再去执行原本的业务逻辑方法,如果执行业务逻辑方法没有
出现异常,那么代理逻辑中就会将事务进行提交,如果执行业务逻辑方法出现了异常,那么则会将事务
进行回滚。
当然,针对哪些异常回滚事务是可以配置的,可以利用 @Transactional 注解中的 rollbackFor 属性进行
配置,默认情况下会对 RuntimeException Error 进行回滚。
spring 事务隔离级别就是数据库的隔离级别:外加一个默认级别
read uncommitted (未提交读)
read committed (提交读、不可重复读)
repeatable read (可重复读)
serializable (可串行化)
数据库的配置隔离级别是 Read Commited, Spring 配置的隔离级别是 Repeatable Read ,请问这时隔离 级别是以哪一个为准?
Spring 配置的为准,如果 spring 设置的隔离级别数据库不支持,效果取决于数据库
Spring Boot Spring MVC Spring 有什么区别
spring 是一个 IOC 容器,用来管理 Bean ,使用依赖注入实现控制反转,可以很方便的整合各种框架,提
AOP 机制弥补 OOP 的代码重复问题、更方便将不同类不同方法中的共同处理抽取成切面、自动注入给
方法执行,比如日志、异常等
springmvc spring web 框架的一个解决方案,提供了一个总的前端控制器 Servlet ,用来接收请求,
然后定义了一套路由策略( url handle 的映射)及适配执行 handle ,将 handle 结果使用视图解析技术
生成视图展现给前端
springboot spring 提供的一个快速开发工具包,让程序员能更方便、更快速的开发 spring+springmvc
应用,简化了配置(约定了默认配置),整合了一系列的解决方案( starter 机制)、 redis
mongodb es ,可以开箱即用
  • 21
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

师范大学通信大怨总

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值