1,struts2
1,struts2的工作原理
客户端发送请求--》请求经过一系列过滤器--》FilterDispatcher通过ActionMapper来决定这个Request需要调用哪个Action --》FilterDispatcher把请求的处理交给ActionProxy--》通过ConfigurationManager询问Struts配置文件(Struts.xml),找到需要调用的Action类--》ActionProxy创建一个ActionInvocation的实例 --》调用Action--》执行完毕,返回结果
2,struts2中的拦截器有什么用,列举提供拦截器的名称
a,拦截器是struts2核心组成部分,它提供了一种机制,使得开发者可以定义一个特定的功能模块,这个模块会在Action执行之前或者之后执行,也可以在Action执行之前阻止Action执行。
b,常用的拦截器有:
chain:在不同请求之间将请求参数在不同名字件转换,请求内容不变
fileUpload:提供文件上传。
i18n:记录用户选择的区域环境
logger:输出Action的名字
params:将请求中的参数设置到Action中去。
3,struts2有哪些优点
a,在软件设计上Struts2的应用可以不依赖于Servlet API和struts API。 Struts2的这种设计属于无侵入式设计;
b,拦截器,实现如参数拦截注入等功能;
c类型转换器,可以把特殊的请求参数转换成需要的类型;
d,多种表现层技术,如:JSP、freeMarker、Velocity等;
e,Struts2的输入校验可以对指定某个方法进行校验;
f,提供了全局范围、包范围和Action范围的国际化资源文件管理实现
g,实现MVC模式,结构清晰,使开发者只关注业务逻辑的实现。有丰富的tag可以用,大大提高了开发效率。(简要)
4,说下Struts的设计模式
MVC设计模式:
web应用程序启动时就会加载并初始化ActionServler。 2)用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法. 3)Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生成动态的网页,返回给客户。
5,拦截器和过滤器的区别
1)拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2)过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3)拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4)拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5)在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
6,ActionContext、ServletContext、pageContext的区别?
1)ActionContext是当前的Action的上下文环境,通过ActionContext可以获取到request、session、ServletContext等与Action有关的对象的引用;
2 )ServletContext是域对象,一个web应用中只有一个ServletContext,生命周期伴随整个web应用;
3)pageContext是JSP中的最重要的一个内置对象,可以通过pageContext获取其他域对象的应用,同时它是一个域对象,作用范围只针对当前页面,当前页面结束时,pageContext销毁, 生命周期是JSP四个域对象中最小的。
7, 拦截器的生命周期与工作过程?
1)每个拦截器都是实现了Interceptor接口的 Java 类;
2)init(): 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化;
3)intercept(ActionInvocation invocation): 每拦截一个动作请求, 该方法就会被调用一次;
4)destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次;
5)struts2中有内置了18个拦截器。
8,用自己的话简要阐述struts2的执行流程。
Struts 2框架本身大致可以分为3个部分:核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。 1)核心控制器FilterDispatcher是Struts 2框架的基础,包含了框架内部的控制流程和处理机制。
2)业务控制器Action和业务逻辑组件是需要用户来自己实现的。用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,供核心控制器FilterDispatcher来使用。 Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,所以说Struts 2是WebWork的升级版本。
基本简要流程如下:
1)客户端浏览器发出HTTP请求。
2)根据web.xml配置,该请求被FilterDispatcher接收。
3)根据struts.xml配置,找到需要调用的Action类和方法, 并通过IoC方式,将值注入给Aciton。
4)Action调用业务逻辑组件处理业务逻辑,这一步包含表单验证。
5)Action执行完毕,根据struts.xml中的配置找到对应的返回结果result,并跳转到相应页面。
6)返回HTTP响应到客户端浏览器。
9. Struts2如何进行校验
编程校验
1 继承ActionSupport,重写validate方法(针对所有方法)(服务器端编程,不推荐)。
2 validateXxx方法(Xxx代表的是方法名,针对某个方法进行效验)。
3 如果有错误就把错误信息放在FieldError中,并且跳转到指定的错误业务类,没有就会进行action方法的调用。
校验框架 每个Action类有一个校验文件,命名 Action类名-validation.xml,且与Action类同目录,这是对action里面所有的方法进行校验。 对Action里面的指定方法做校验使用Action的类名-访问路径_方法名-validation.xml。 如:StudentAction-student_add-validation.xml 在效验文件里又分为两种: 字段校验:字段用什么校验器来校验。 非字段校验:是用校验器校验什么字段。 通俗点讲:字段校验:校验谁,用什么方法。 非字段校验:用什么校验,校验谁 。
a,web中配置struts2
Struts校验的实现
方法拦截器,继承的MethodFilterIntercepter类。如果配置任何参数,默认对所有方法进行拦截。通过includeMethods对指定方法进行拦截。也可以通过excludeMethods对指定方法不进行拦截。其他的和普通拦截器一样。
2,springMVC
1、什么是Spring MVC ?简单介绍下你对springMVC的理解?
Spring MVC是一个基于Java的实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行职责解耦,把复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。
2,SpringMVC的流程?
(1)用户发送请求至前端控制器DispatcherServlet;
(2) DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handle;
(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet;
(4)DispatcherServlet 调用 HandlerAdapter处理器适配器;
(5)HandlerAdapter 经过适配调用 具体处理器(Handler,也叫后端控制器);
(6)Handler执行完成返回ModelAndView;
(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;
(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;
(9)ViewResolver解析后返回具体View;
(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
(11)DispatcherServlet响应用户。
3,springMVC的优点
(1)可以支持各种视图技术,而不仅仅局限于JSP;
(2)与Spring框架集成(如IoC容器、AOP等);
(3)清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。
(4) 支持各种请求资源的映射策略。
4,Spring MVC的主要组件?
(1)前端控制器 DispatcherServlet(不需要程序员开发)
作用:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
(2)处理器映射器HandlerMapping(不需要程序员开发)
作用:根据请求的URL来查找Handler
(3)处理器适配器HandlerAdapter
注意:在编写Handler的时候要按照HandlerAdapter要求的规则去编写,这样适配器HandlerAdapter才可以正确的去执行Handler。
(4)处理器Handler(需要程序员开发)
(5)视图解析器 ViewResolver(不需要程序员开发)
作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)
(6)视图View(需要程序员开发jsp)
View是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)
5,springMVC和struts2的区别有哪些?
(1)springmvc的入口是一个servlet即前端控制器(DispatchServlet),而struts2入口是一个filter过虑器(StrutsPrepareAndExecuteFilter)。
(2)springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
(3)Struts采用值栈存储请求和响应的数据,通过OGNL存取数据,springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
6,SpringMVC怎么样设定重定向和转发的?
(1)转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"
(2)重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"
7,SpringMVC常用的注解有哪些?
@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。
@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。
一般用@Conntroller注解控制器,表示是表现层,不能用别的注解代替
8,Struts和SpringMVC的区别
Struts的核心控制器是Filter,SpringMVC的核心控制器是一个Servlet。Struts采用配置式编程。SpringMVC主要使用注解编程。SpringMVC比Struts代码更直观,更简洁。
编写SpringMVC配置
在web.xml当中配置SpringMVC.
编写代码
SpringMVC注解
@Controller 该注解用来标记一个Controller。
@RequestMapping 请求映射,该注解将一个请求映射到具体的方法当中。该注解既可以注解类,也可以注解方法。但是类上上面可以没有该注解,但是方法必须有。
@RequestMapping(”hello”);简写。通过hello访问方法
@RequestMapping(value=”hello”);标准写法。通过hello访问方法
@RequestMapping可传入的参数 value:访问的路径(必须的)method: 请求的方式get\post…… (可选)params: 请求必须传入的参数 (可选)
@RequestParam(name=”xxx”) String aaa;该注解用来获取请求当中的参数,相当远String aaa = request.getParamter(“xxx”);当前台传入的参数名与controller方法输入参数的参数名一致时,该注解可以省略不写。
@PathVariable("id")从请求路径当中获取参数,需要RequestMapping配合。
@ResponseBody 该注解标识返回的内容是一个ResponseBody。一般用于ajax请求。或者文件下载。
3,spring
1,使用spring框架的好处
a,轻量级,spring是轻量的,基本版本大概2MB
b,控制反转,spring通过控制反转实现松散耦合,对象给出他们依赖,而不是创建或查找依赖的对象们
c,面向切面的编程AOP,spring支持面向切面的编程,并且把业务应用逻辑和系统服务逻辑分开
d,MVC框架Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
e,事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
f,异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
2, 有哪些不同类型的IOC(依赖注入)方式?
- 构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
- Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。
3,你怎样定义类的作用域?
当定义一个<bean> 在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean 定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。
4,解释Spring支持的几种bean的作用域。
Spring框架支持以下五种bean的作用域:
- singleton : bean在每个Spring ioc 容器中只有一个实例。
- prototype:一个bean的定义可以有多个实例。
- request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
- session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
- global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
缺省的Spring bean 的作用域是Singleton.
5,解释Spring框架中bean的生命周期。
- Spring容器 从XML 文件中读取bean的定义,并实例化bean。
- Spring根据bean的定义填充所有的属性。
- 如果bean实现了BeanNameAware 接口,Spring 传递bean 的ID 到 setBeanName方法。
- 如果Bean 实现了 BeanFactoryAware 接口, Spring传递beanfactory 给setBeanFactory 方法。
- 如果有任何与bean相关联的BeanPostProcessors,Spring会在postProcesserBeforeInitialization()方法内调用它们。
- 如果bean实现IntializingBean了,调用它的afterPropertySet方法,如果bean声明了初始化方法,调用此初始化方法。
- 如果有BeanPostProcessors 和bean 关联,这些bean的postProcessAfterInitialization() 方法将被调用。
- 如果bean实现了 DisposableBean,它将调用destroy()方法。
6,在 Spring中如何注入一个java集合?
Spring提供以下几种集合的配置元素:
- <list>类型用于注入一列值,允许有相同的值。
- <set> 类型用于注入一组值,不允许有相同的值。
- <map> 类型用于注入一组键值对,键和值都可以为任意类型。
- <props>类型用于注入一组键值对,键和值都只能为String类型。
7,Spring注解
基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。另一个例子是@Bean注解, 它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
@Required 注解,这个注解表明bean的属性必须在配置的时候设置,通过一个bean定义的显式的属性值或通过自动装配,若 @Required注解的bean属性未被设置,容器将抛出BeanInitializationException
@Autowired 注解,@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。
@Qualifier 注解 ,当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定需要装配的确切的bean。
8,使用Spring通过什么方式访问Hibernate?
在Spring中有两种方式访问Hibernate:
- 控制反转 Hibernate Template和 Callback。
- 继承 HibernateDAOSupport提供一个AOP 拦截器。
9,Spring面向切面编程(AOP)
1,解释AOP:面向切面的编程,或AOP, 是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。
2,Aspect 切面:AOP核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组API提供横切功能。比如,一个日志模块可以被称作日志的AOP切面。根据需求的不同
3,在Spring AOP 中,关注点和横切关注的区别是什么?关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。
4,连接点 :连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个AOP切面,它实际上是个应用程序执行Spring AOP的位置。
5,通知:
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。
Spring切面可以应用五种类型的通知:
- before:前置通知,在一个方法执行前被调用。
- after: 在方法执行之后调用的通知,无论方法执行是否成功。
- after-returning: 仅当方法成功完成后执行的通知。
- after-throwing: 在方法抛出异常退出时执行的通知。
- around: 在方法执行之前和之后调用的通知。
6,切点:切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。
7,什么是引入:引入允许我们在已存在的类中增加新的方法和属性
8,什么是目标对象?:被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(advised)对象。
9,什么是代理?:代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。
10
Spring IoC创建对象的几种形式
依赖注入
Spring注解编程
@Component 标有该注解的类是一个需要Spring 管理的bean
相当于配置文件中
<bean id="hello" class="com.linksky.spring.annotation.Hello"></bean>
@Component("wor")指定id
@Repository 该注解一般用于注解Dao层。
@service 该注解一般用于注解service层。
@Controller 用来注解Controller
@Lazy(”true”) 注解延迟加载
@Scope(”prototype”) 注解的是单例多例
属性注解
主要注解依赖关系
@Autowired 自动注入,他会根据class 类型进行注入。
@Qualifier("") 该注解会和@Autowired连用。由@Autowired指明类型。@Qualifier("")指明id或者name
面向切面
4,mybatis
1,什么是Mybatis?
(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。
(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
(3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。
2,Mybaits的优点:
(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(4)能够与Spring很好的集成;
(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
3,mybatis的缺点
(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4,MyBatis框架适用场合:
(1)MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。
(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。
5,MyBatis与Hibernate有哪些不同?
(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。
(2)Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。
(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。
6,#{}和${}的区别是什么?
#{}是预编译处理,${}是字符串替换。
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理${}时,就是把${}替换成变量的值。
使用#{}可以有效的防止SQL注入,提高系统安全性
7,当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
8,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
Dao接口即Mapper接口。接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法内的参数,就是传递给sql的参数。
Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MapperStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MapperStatement对象。
Mapper接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。Mapper 接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Mapper接口生成代理对象proxy,代理对象会拦截接口方法,转而执行MapperStatement所代表的sql,然后将sql执行结果返回。
9,Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页。可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
10,Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用<resultMap>标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用sql列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
11,为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?
Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。
12,Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。
13,Mybatis的一级、二级缓存
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置<cache/> ;
3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。
14,简述Mybatis的插件运行原理,以及如何编写一个插件。
Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
编写插件:实现Mybatis的Interceptor接口并复写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
15,Mybatis和JDBC比较
JDBC
优点:jdbc是java提供的一套操作数据库的标准接口。它和java的结合相对比较紧密,执行效率比较高。
缺点:有大量冗余代码,开发效率相对较低。代码的可读性和维护性较差。
Mybatis
优点:对jdbc进行的封装代码简介。开发效率相对较高。程序的可读性,维护性都有所提高。Mybatis将SQL语句从程序剥离出来。降低了和程序的耦合度,更便于对SQL进行优化。
16,Mybatis和Hibernate比较
Hibernate优点
Hibernate 是一款持久层框架,同时也是一款ORM框架。Hibernate直接操作的是对象,是程序更直观更易于理解,使用hibernate框架不用关心SQL的具体实现。便于数据库迁移。Hibernate可以根据实体类生成数据库表。
Hibernate缺点
Hibernate无法定制SQL语句,无法再SQL层面对程序进行优化,当数据量级过大的时候,hibernate将不再适用。一般hibernate之应用于企业应用当中。Mybatis应用于网络应用(互联网项目)。
17,
18,ResultType和ResultMap的区别
为了解决数据库表和实体类属性名称不一致问题,Mybatis框架提供了ResultMap工具对属性和字段进行统一映射。ResultType对应的实体类,一般在实体属性和字段一致的时候使用。如果有关联关系的对象,必须是用ResultMap进行映射。
ResultMap的使用
19,动态sql
Sql标签
If标签
Choose标签
Choose相当于java里面的if……else……,但是我们动态没有if……else……所以使用choose.
Where标签
Where标签相当于where关键字,但是该标签会自动去掉第一个拼接关键字(and或or)。
Set标签
Set标签相当于set关键字,他可以去掉最后一个要修改的属性后面的逗号。
Trim标签
Foreach标签
5,hibernate
1,Hibernate工作原理及为什么要用
1.读取并解析配置文件
2.读取并解析映射信息,创建SessionFactory
3.打开Sesssion
4.创建事务Transation
5.持久化操作
6.提交事务
7.关闭Session
8.关闭SesstionFactory
1. 对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
Hibernate是一个基于JDBC的主流持久化框架,是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作
hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
hibernate的性能非常好,因为它是个轻量级框架。映射的灵活性很出色。它支持各种关系数据库,从一对一到多对多的各种复杂关系。
2,Hibernate是如何延迟加载?
当Hibernate在查询数据的时候,数据并没有存在与内存中,当程序真正对数据的操作时,对象才存在与内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能
3,说下Hibernate的缓存机制
-
内部缓存存在Hibernate中又叫一级缓存,属于应用事物级缓存,一级缓存是session级别的缓存,只有在同一个session中有效,其他session无法读取该缓存内的数据。session关闭缓存失效。一级缓存由hibernate管理控制,程序员无法通过程序控制。
-
二级缓存:二级缓存是SessionFactory级别的缓存,在整个SessionFactory的生命周期内,该换一直有效。SessionFactory关闭,缓存失效。该缓存内的数据,可以在不再不同Session之间共享。Hibernate框架没有实现该缓存。并且默认关闭了二级缓存。
a) 应用及缓存
b) 分布式缓存
条件:数据不会被第三方修改、数据大小在可接受范围、数据更新频率低、同一数据被系统频繁使用、非关键数据
c) 第三方缓存的实现
4,如何优化Hibernate?
1.使用双向一对多关联,不使用单向一对多
2.灵活使用单向一对多关联
3.不用一对一,用多对一取代
4.配置对象缓存,不使用集合缓存
5.一对多集合使用Bag,多对多集合使用Set
6. 继承类使用显式多态
7. 表字段要少,表关联不要怕多,有二级缓存撑腰
5,谈谈Hibernate中inverse的作用
inverse属性默认是false,就是说关系的两端都来维护关系。
比如Student和Teacher是多对多关系,用一个中间表TeacherStudent维护。Gp)i
如果Student这边inverse=”true”, 那么关系由另一端Teacher维护,就是说当插入Student时,不会操作TeacherStudent表(中间表)。只有Teacher插入或删除时才会触发对中间表的操作。所以两边都inverse=”true”是不对的,会导致任何操作都不触发对中间表的影响;当两边都inverse=”false”或默认时,会导致在中间表中插入两次关系。
6,JDBC hibernate 和 ibatis 的区别
jdbc:手动
手动写sql
delete、insert、update要将对象的值一个一个取出传到sql中,不能直接传入一个对象。
select:返回的是一个resultset,要从ResultSet中一行一行、一个字段一个字段的取出,然后封装到一个对象中,不直接返回一个对象。
ibatis的特点:半自动化
sql要手动写
delete、insert、update:直接传入一个对象
select:直接返回一个对象
hibernate:全自动
不写sql,自动封装
delete、insert、update:直接传入一个对象
select:直接返回一个对象
7,Hibernate的五个核心接口
Configuration 接口:配置Hibernate,根据其启动hibernate,创建
SessionFactory 对象;
SessionFactory 接口:初始化Hibernate,充当数据存储源的代理,创建
session 对象,sessionFactory 是线程安全的,意味着它的同一个实例可以被应
用的多个线程共享,是重量级、二级缓存;
Session 接口:负责保存、更新、删除、加载和查询对象,是线程不安全的,
避免多个线程共享同一个session,是轻量级、一级缓存;
Transaction 接口:管理事务;
Query 和Criteria 接口:执行数据库的查询。
8,
Hibernate常用类
Configuration Hibernate配置文件加载类。用来加载hibernate配置文件。
SessionFactory Hibernate Session工厂类。用工厂模式创建Session的。
Session 会话。应用程序和数据库的会话。可以直接使用session操作数据。
Transaction Hibernate事务类,用来管理hibernate框架的事务。
Hibernate的执行流程
Hibernate对象的三种状态
Hibernate将所操作的对象分为三种状态,这三种状态分别是瞬态、持久态、游离态。瞬态是指刚被创建的 对象,该对象存在于虚拟机内存。持久态,瞬态对象通过hibernate中提供的方法和hibernate session进 行 关联,该对象就成为一个持久态对象,持久态对象存在于hibernate session缓存当中。游离态对 象,事务一旦提交,数据进入数据库,该对象就是变成一个游离态对象。
瞬态
对象刚被创建。这是一个临时状态的对象。等待hibernate将其转化持久态。
持久态
与hibernate session 建立关联。如果事务提交,并且和session脱离联系。该对象就变成游离态。如果事务 不提交,该对象与session脱离联系,该对象还是瞬态。
游离态
对象已经存在于数据当中,并与session脱离联系。
Hibernate延迟加载
当对有关联关系的对象进行查询的时候,如果使用的JDBC则需要进行多表查询。这个时候无论数据是否被使 用,都会一次性将数据拿出。使用hibernate框架之后,框架默认开启了,延迟加载机制。就是只查询主对象, 关联对象如果没有使用,则不会进行查询。
Lazy: proxy.使用代理模式实现。no-proxy:不使用代理。false,关闭延迟加载。
6,springboot
1,什么是springboot
用来简化spring应用的初始搭建以及开发过程 使用特定的方式来进行配置(properties或yml文件)
创建独立的spring引用程序 main方法运行
嵌入的Tomcat 无需部署war文件
简化maven配置
自动配置spring添加对应功能starter自动化配置
答:spring boot来简化spring应用开发,约定大于配置,去繁从简,just run就能创建一个独立的,产品级别的应用
2,Spring Boot有哪些优点?
答:-快速创建独立运行的spring项目与主流框架集成
-使用嵌入式的servlet容器,应用无需打包成war包
-starters自动依赖与版本控制
-大量的自动配置,简化开发,也可修改默认值
-准生产环境的运行应用监控
-与云计算的天然集成
3,Spring Boot中的监视器是什么?
Spring boot actuator是spring启动框架中的重要功能之一。Spring boot监视器可帮助您访问生产环境中正在运行的应用程 序的当前状态。
有几个指标必须在生产环境中进行检查和监控。即使一些外部应用程序可能正在使用这些服务来向相关人员触发警报消 息。监视器模块公开了一组可直接作为HTTP URL访问的REST端点来检查状态。
4,springboot常用的starter有哪些
spring-boot-starter-web 嵌入tomcat和web开发需要servlet与jsp支持
spring-boot-starter-data-jpa 数据库支持
spring-boot-starter-data-redis redis数据库支持
spring-boot-starter-data-solr solr支持
mybatis-spring-boot-starter 第三方的mybatis集成starter
5,springboot自动配置的原理
在spring程序main方法中 添加@SpringBootApplication或者@EnableAutoConfiguration
会自动去maven中读取每个starter中的spring.factories文件 该文件里配置了所有需要被创建spring容器中的bean
6,springboot读取配置文件的方式
springboot默认读取配置文件为application.properties或者是application.yml
7,.常见的starter会包几个方面的内容。分别是什么。
常见的starter会包括下面四个方面的内容
自动配置文件,根据classpath是否存在指定的类来决定是否要执行该功能的自动配置。 spring.factories,非常重要,指导Spring Boot找到指定的自动配置文件。 endpoint:可以理解为一个admin,包含对服务的描述、界面、交互(业务信息的查询)。 health indicator:该starter提供的服务的健康指标。
两个需要注意的点:
1. @ConditionalOnMissingBean的作用是:只有对应的bean在系统中都没有被创建,它修饰的初始化代码块才会执行,【用户自己手动创建的bean优先】。
2. Spring Boot Starter找到自动配置文件(xxxxAutoConfiguration之类的文件)的方式有两种:spring.factories:由Spring Boot触发探测classpath目录下的类,进行自动配置; @EnableXxxxx:有时需要由starter的用户触发*查找自动配置文件的过程
8,谈谈你对Spring Boot的认识
spring Boot是一个开源框架,它可用于创建可执行的Spring应用程序,采用了习惯优于配置的方法。此框架的神奇之处在于@EnableAutoConfiguration注解,此注释自动载入应用程序所需的所有Bean——这依赖于Spring Boot在类路径中的查找。
1. @Enable*注释 @Enable*注释并不是新发明的注释,早在Spring 3框架就引入了这些注释,用这些注释替代XML配置文件。 很多Spring开发者都知道@EnableTransactionManagement注释,它能够声明事务管理;@EnableWebMvc注释,它能启用Spring MVC;以及@EnableScheduling注释,它可以初始化一个调度器。
2. 属性映射 下面看MongoProperties类,它是一个Spring Boot属性映射的例子: @ConfigurationProperties(prefix = "spring.data.mongodb") public class MongoProperties { private String host; private int port = DBPort.PORT; private String uri = "mongodb://localhost/test"; private String database; // ... getters/ setters omitted } @ConfigurationProperties注释将POJO关联到指定前缀的每一个属性。例如,spring.data.mongodb.port属性将映射到这个类的端口属性。 强烈建议Spring Boot开发者使用这种方式来删除与配置属性相关的瓶颈代码。
3.@Conditional注释 Spring Boot的强大之处在于使用了Spring 4框架的新特性:@Conditional注释,此注释使得只有在特定条件满足时才启用一些配置。 在Spring Boot的org.springframework.boot.autoconfigure.condition包中说明了使用@Conditional注释能给我们带来什么,下面对这些注释做一个概述: @ConditionalOnBean @ConditionalOnClass @ConditionalOnExpression @ConditionalOnMissingBean @ConditionalOnMissingClass @ConditionalOnNotWebApplication @ConditionalOnResource @ConditionalOnWebApplication
4.应用程序上下文初始化器 spring.factories还提供了第二种可能性,即定义应用程序的初始化。这使得我们可以在应用程序载入前操纵Spring的应用程序上下文ApplicationContext。 特别是,可以在上下文创建监听器,使用ConfigurableApplicationContext类的addApplicationListener()方法。 AutoConfigurationReportLoggingInitializer监听到系统事件时,比如上下文刷新或应用程序启动故障之类的事件,Spring Boot可以执行一些工作。这有助于我们以调试模式启动应用程序时创建自动配置的报告。 要以调试模式启动应用程序,可以使用-Ddebug标识,或者在application.properties文件这添加属性debug= true。
7,dubbo
Dubbo |db|是一个由阿里巴巴开源的、分布式的RPC(Remote Procedure Call Protocol-远程过程调用)和微服务框架,现为Apache顶级项目。
Dubbo提供了三个关键功能:基于接口的远程调用,容错与负载均衡,服务自动注册与发现。
Dubbo使得调用远程服务就像调用本地java服务一样简单。
· Provider: 暴露服务的服务提供方。
· Consumer: 调用远程服务的服务消费方。
· Registry: 服务注册与发现的注册中心。
· Monitor: 统计服务的调用次调和调用时间的监控中心。
· Container: 服务运行容器。
调用关系说明:
服务容器负责启动,加载,运行服务提供者。
服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者在启动时,向注册中心订阅自己所需的服务。
注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
Dubbo提供了很多协议,Dubbo协议、RMI协议、Hessian协议,Dubbo源代码有各种协议的实现,我们之前没用Dubbo之前时,大部分都用Hessian来使用我们服务的暴露和调用,利用HessianProxyFactory调用远程接口。
Dubbo原理
初始化过程细节: 第一步,就是将服务装载容器中,然后准备注册服务。和spring中启动过程类似,spring启动时,将bean装载进容器中的时候,首先要解析bean。所以dubbo也是先读配置文件解析服务。
解析服务:
1)、基于dubbo.jar内的Meta-inf/spring.handlers配置,spring在遇到dubbo名称空间时,会回调DubboNamespaceHandler类。
2)、所有的dubbo标签,都统一用DubboBeanDefinitionParser进行解析,基于一对一属性映射,将XML标签解析为Bean对象。生产者或者消费者初始化的时候,会将Bean对象转会为url格式,将所有Bean属性转成url的参数。 然后将URL传给Protocol扩展点,基于扩展点的Adaptive机制,根据URL的协议头,进行不同协议的服务暴露和引用。
暴露服务:
a、 直接暴露服务端口
在没有使用注册中心的情况,这种情况一般适用在开发环境下,服务的调用这和提供在同一个IP上,只需要打开服务的端口即可。 即,当配置 or ServiceConfig解析出的URL的格式为: Dubbo://service-host/com.xxx.TxxService?version=1.0.0 基于扩展点的Adaptiver机制,通过URL的“dubbo://”协议头识别,直接调用DubboProtocol的export()方法,打开服务端口。
b、向注册中心暴露服务:
和上一种的区别:需要将服务的IP和端口一同暴露给注册中心。 ServiceConfig解析出的url格式为: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?export=URL.encode(“dubbo://service-host/com.xxx.TxxService?version=1.0.0”)
基于扩展点的Adaptive机制,通过URL的“registry://”协议头识别,调用RegistryProtocol的export方法,将export参数中的提供者URL先注册到注册中心,再重新传给Protocol扩展点进行暴露: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
引用服务:
a、直接引用服务:
在没有注册中心的,直连提供者情况下, ReferenceConfig解析出的URL格式为: Dubbo://servicehost/com.xxx.TxxService?version=1.0.0
基于扩展点的Adaptive机制,通过url的“dubbo://”协议头识别,直接调用DubboProtocol的refer方法,返回提供者引用。
b、从注册中心发现引用服务:
此时,ReferenceConfig解析出的URL的格式为: registry://registry-host/com.alibaba.dubbo.registry.RegistryService?refer=URL.encode(“consumer://consumer-host/com.foo.FooService?version=1.0.0”)
基于扩展点的Apaptive机制,通过URL的“registry://”协议头识别,就会调用RegistryProtocol的refer方法,基于refer参数总的条件,查询提供者URL,如: Dubbo://service-host/com.xxx.TxxService?version=1.0.0
基于扩展点的Adaptive机制,通过提供者URL的“dubbo://”协议头识别,就会调用DubboProtocol的refer()方法,得到提供者引用。 然后RegistryProtocol将多个提供者引用,通过Cluster扩展点,伪装成单个提供这引用返回。
四、服务提供与消费详细过程
服务提供者暴露一个服务的详细过程
暴露服务的主过程:
首先ServiceConfig类拿到对外提供服务的实际类ref,然后将ProxyFactory类的getInvoker方法使用ref生成一个AbstractProxyInvoker实例,到这一步就完成具体服务到invoker的转化。接下来就是Invoker转换到Exporter的过程。 Dubbo处理服务暴露的关键就在Invoker转换到Exporter的过程,下面我们以Dubbo和rmi这两种典型协议的实现来进行说明: Dubbo的实现: Dubbo协议的Invoker转为Exporter发生在DubboProtocol类的export方法,它主要是打开socket侦听服务,并接收客户端发来的各种请求,通讯细节由dubbo自己实现。 Rmi的实现: RMI协议的Invoker转为Exporter发生在RmiProtocol类的export方法,他通过Spring或Dubbo或JDK来实现服务,通讯细节由JDK底层来实现。
服务消费的主过程
服务消费的主过程:
首先ReferenceConfig类的init方法调用Protocol的refer方法生成Invoker实例。接下来把Invoker转为客户端需要的接口