SSM First Blood

Spring

1.Spring 是什么?

Spring 是一个轻量级的 IoC 和 AOP 容器框架。是为 Java 应用程序提供基础性服务的一套框架,目的是用于简化企业应用程序的开发,它使得开发者只需要关心业务需求。常见的配置方式有三种:基于 XML 的配置.基于注解的配置.基于 Java 的配置。

主要由以下几个模块组成:

Spring Core:核心类库,提供 IOC 服务;

Spring Context:提供框架式的 Bean 访问方式,以及企业级功能(JNDI.定时任务等);

Spring AOP:AOP 服务;

Spring DAO:对 JDBC 的抽象,简化了数据访问异常的处理;

Spring ORM:对现有的 ORM 框架的支持;

Spring Web:提供了基本的面向 Web 的综合特性,例如多方文件上传;

Spring MVC:提供面向 Web 应用的 Model-View-Controller 实现。

2 Spring 的 AOP 理解?

OOP 面向对象,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。 AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务 无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低 了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证.日志.事务处理。AOP 实现的关键在于代理模式,AOP 代理主要分为静态代理和动态代理。静态代理的代表为 AspectJ;动态代理则以 Spring AOP 为代表。

(1)AspectJ 是静态代理的增强,所谓静态代理,就是 AOP 框架会在编译阶段生成 AOP 代理类,因此也称为编译时增强,他会在编译阶段将AspectJ(切面)织入到 Java 字节码中,运行的时候就是增强之后的 AOP 对象。

扫描二维码关注公众号,回复: 16175474 查看本文章

(2)Spring AOP 使用的动态代理,所谓的动态代理就是说 AOP 框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个 AOP 对象,这个AOP 对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回 调原对象的方法。

Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理:

(1)JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler接口和 Proxy 类,InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起,Proxy 利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

(2)如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP 会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现 AOP。CGLIB 是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。

(3)静态代理与动态代理区别在于生成 AOP 代理对象的时机不同,相对来说 AspectJ 的静态代理方式具有更好的性能,但是 AspectJ 需要特定的编译器进行处理,而 Spring AOP 则无需特定的编译器处理。InvocationHandler invoke(Object proxy,Method method,Object[] args):proxy 是最终生成的代理实例;method 是被代理目标实例的某个具体方法;args 是被代理目标实例某个方法的具体入参, 在方法反射调用时使用。

3 Spring 的 IOC 理解?

(1)IOC 就是控制反转,是指创建对象的控制权的转移,以前创建对象的 主动权和时机是由自己把控的,而现在这种权力转移到 Spring 容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。DI 依赖注入,和控制反转是同一个概念的不同角度的描述,即 应用程序在运行时依赖 IoC 容器来动态注入对象需要的外部资源。

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

(3)Spring 的 IOC 有三种注入方式 :构造器注入, setter 方法注入, 根据注解注入。IOC 让相互协作的组件保持松散的耦合,而 AOP 编程允许你把遍布于应用各层的功能分离出来形成可重用的功能组件。

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

首先说一下 Servlet 的生命周期:实例化,初始 init,接收请求 service,销毁 destroy;Spring 上下文中的 Bean 生命周期也类似,如下:

(1)实例化 Bean:对于 BeanFactory 容器,当客户向容器请求一个尚未初始化的 bean 时,或初始化 bean 的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean 进行实例化。对于 ApplicationContext 容器,当容器启动结束后,通过获取 BeanDefinition 对象中的信息,实例化所有的 bean。

(2)设置对象属性(依赖注入): 实例化后的对象被封装在 BeanWrapper 对象中,紧接着,Spring 根据BeanDefinition 中的信息 以及 通过 BeanWrapper 提供的设置属性的接口完成依赖注入。

(3)处理 Aware 接口:接着,Spring 会检测该对象是否实现了 xxxAware 接口,并将相关的 xxxAware 实例注入给 Bean:如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的setBeanName(String beanId)方法,此处传递的就是 Spring 配置文件中 Bean的 id 值;如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的setBeanFactory()方法,传递的是 Spring 工厂自身。如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用setApplicationContext(ApplicationContext)方法,传入 Spring 上下文;

(4)BeanPostProcessor: 如果想对 Bean 进行一些自定义的处理,那么可以让 Bean 实现了BeanPostProcessor 接口,那将会调用 postProcessBeforeInitialization(Object obj, String s)方法。由于这个方法是 在 Bean 初始化结束时调用的,所以可以被应用于内存或缓存技术;

(5)InitializingBean 与 init-method:如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。

(6)如果这个 Bean 实现了 BeanPostProcessor 接口,将会调用 postProcessAfterInitialization(Object obj, String s)方法;以上几个步骤完成后,Bean 就已经被正确创建了,之后就可以使用这个 Bean 了。

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

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

5.Spring 支持的几种 bean 的作用域。

Spring 容器中的 bean 可以分为 5 个范围:

(1)singleton:默认,每个容器中只有一个 bean 的实例,单例的模式由BeanFactory 自身来维护。

(2)prototype:为每一个 bean 请求提供一个实例。

(3)request:为每一个网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

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

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

SpringMvc

1.什么是 SpringMVC

SpringMVC 是一个基于 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)前端控制器 DispatcherServlet(不需要程序员开发)作用:接收请求.响应结果,相当于转发器,有了 DispatcherServlet 就减少了其它组件之间的耦合度。

(2)处理器映射器 HandlerMapping(不需要程序员开发)作用:根据请求的 URL 来查找 Handler

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

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

(5)视图解析器 ViewResolver(不需要程序员开发)作用:进行视图的解析,根据视图逻辑名解析成真正的视图(view)

(6)视图 View(需要程序员开发 jsp)View 是一个接口, 它的实现类支持不同的视图类型(jsp,freemarker,pdf等等)

4.SpringMVC 里面拦截器是怎么写的

有两种写法,一种是实现 HandlerInterceptor 接口,另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在 SpringMVC 的配置文件中配置拦截器即可:

<!-- 配置 SpringMVC 的拦截器 --> 
<mvc:interceptors> <!-- 配置一个拦截器的 Bean 就可以了 默认是对所有请求都拦截 --> 
    <bean id="myInterceptor" class="com.zwp.action.MyHandlerInterceptor"></bean> <!-- 只针对部分请求拦截 --> 
    <mvc:interceptor> 
        <mvc:mapping path="/modelMap.do" /> 
        <bean class="com.zwp.action.MyHandlerInterceptorAdapter" /> 
    </mvc:interceptor> 
</mvc:interceptors>

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.Mybatis 的一级.二级缓存

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作 用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存且不能关闭。

2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache, HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自 定义存储源,如 Ehcache。默认不打开二级缓存,要手动开启二级缓存,使用 二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置。3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear。

3.resultType resultMap 的区别?

1.类的名字和数据库相同时,可以直接设置resultType参数为Pojo类

2.若不同,需要设置resultMap将结果名字和Pojo名字进行转换

4.使用MyBatis的mapper接口调用时有哪些要求?

类型相同

1.Mapper接口方法名和mapper.xml中定义的每个sql的id相同

2.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的 parameterType的类型相同

3.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的 resultType的类型相同

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

猜你喜欢

转载自blog.csdn.net/Your1221/article/details/118383366
ssm
今日推荐