Spring 的核心特性是什么?Spring 优点?
Spring 的核心是控制反转(IoC)和面向切面(AOP)
Spring 优点:
程序员必须掌握的Java 框架,学会之后50k不是问题
(1)方便解耦,简化开发 (高内聚低耦合)
Spring 就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给 Spring管理
spring 工厂是用于生成 bean
(2)AOP 编程的支持
Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
(3) 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
(4) 方便程序的测试
Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序
(5)方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持
(6) 降低 JavaEE API 的使用难度
Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低
spring 框架中需要引用哪些 jar 包,以及这些 jar 包的用途
4 + 1 : 4 个 核 心 ( beans 、 core 、 context 、 expression ) + 1 个 依 赖(commons-loggins…jar)
理解 AOP、IoC 的基本原理;
IOC:控制反转(IoC)与依赖注入(DI)是同一个概念,
控制反转的思想:
传统的 java 开发模式中,当需要一个对象时,我们会自己使用 new 或者getInstance 等直接或者间接调用构造方法创建一个对象。而在 spring 开发模式中,spring 容器使用了工厂模式为我们创建了所需要的对象,不需要我们自己创建了,直接调用 spring 提供的对象就可以了
引入 IOC 的目的:
(1)脱开、降低类之间的耦合;(2)倡导面向接口编程、实施依赖倒换原则;
(3)提高系统可插入、可测试、可修改等特性
AOP:面向切面编程(AOP)面向切面编程思想:
在面向对象编程(oop)思想中,我们将事物纵向抽成一个个的对象。而在面向切面编程中,我们将一个个的对象某些类似的方面横向抽成一个切面,对这个切面进行一些如权限控制、事物管理,记录日志等公用操作处理的过程。
切面:简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。
AOP 底层:动态代理。
如果是接口采用 JDK 动态代理,如果是类采用 CGLIB 方式实现动态代理。
AOP 的一些场景应用;
AOP 用来封装横切关注点,具体可以在下面的场景中使用:
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
spring 注入的几种方式
(1)构造方法注入
(2)setter 注入
(3)基于注解
Spring 中 Bean 的作用域有哪些
作用域:用于确定 spring 创建 bean 实例个数
取值(常用的两个):
singleton 单例,默认值。prototype 多例,一个 bean 的定义可以有多个实例。每执行一次 getBean 将获得一个实例。
请介绍一下 bean 的生命周期
(1)bean 定义:在配置文件里面用来进行定义。
(2)bean 初始化:有两种方式初始化:在配置文件中通过指定 init-method 属性来完成实现
org.springframwork.beans.factory.InitializingBean 接口
(3)bean 调用:有三种方式可以得到 bean 实例,并进行调用
(4)bean 销毁:销毁有两种方式使用配置文件指定的 destroy-method 属性实现
org.springframwork.bean.factory.DisposeableBean 接口
Spring 中自动装配的方式有哪些
no:不进行自动装配,手动设置 Bean 的依赖关系。
byName:根据 Bean 的名字进行自动装配。
byType:根据 Bean 的类型进行自动装配。
constructor:类似于 byType,不过是应用于构造器的参数,如果正好有一个 Bean与构造器的参数类型相同则可以自动装配,否则会导致错误。autodetect:如果有默认的构造器,则通过 constructor 的方式进行自动装配,否则使用 byType 的方式进行自动装配。
(自动装配没有自定义装配方式那么精确,而且不能自动装配简单属性(基本类型、字符串等),在使用时应注意。)
@Resource 和 @Autowired 区别?分别用在什么场景?
(1)共同点:两者都可以写在字段和 setter 方法上。两者如果都写在字段上,那么就不需要再写 setter 方法。
(2)不同点:
@Autowired
@Autowired为Spring提供的注解,需要导入包
org.springframework.beans.factory.annotation.Autowired;只按照 byType 注入。@Autowired 注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier 注解一起使用。
@Resource
@Resource 默 认 按 照 ByName 自 动 注 入 , 由 J2EE 提 供 , 需 要 导 入 包javax.annotation.Resource。@Resource 有两个重要的属性:name 和 type,而 Spring将@Resource 注解的 name 属性解析为 bean 的名字,而 type 属性则解析为 bean的类型。所以,如果使用 name 属性,则使用 byName 的自动注入策略,而使用type 属性时则使用 byType 自动注入策略。如果既不制定 name 也不制定 type 属性,这时将通过反射机制使用 byName 自动注入策略。
Hibernate 和 mybatis 的区别?
(1)两者最大的区别
针对简单逻辑,Hibernate 与 MyBatis 都有相应的代码生成工具,可以生成简单基本的 DAO 层方法。
针对高级查询,MyBatis 需要手动编写 SQL 语句,以及 ResultMap,而 Hibernate有良好的映射机制,开发者无需关心 SQL 的生成与结果映射,可以更专注于流程。
(2)开发难度对比
Hibernate 的开发难度大于 MyBatis,主要由于 Hibernate 比较复杂,庞大,学习周期比较长。
MyBatis 则相对简单,并且 MyBatis 主要依赖于生气了的书写,让开发者刚进更熟悉。
(3)sql 书写比较
Hibernate 也可以自己写 sql 来指定需要查询的字段,但这样就破坏了Hibernate 开发的简洁性,不过 Hibernate 具有自己的日志统计。
MyBatis 的 sql 是手动编写的,所以可以按照要求指定查询的字段,不过没有自己的日志统计,所以要借助 Log4j 来记录日志。
(4)数据库扩展性计较Hibernate 与数据库具体的关联在 XML 中,所以 HQL 对具体是用什么数据库
并不是很关心MyBatis 由于所有 sql 都是依赖数据库书写的,所以扩展性、迁移性比较差。
(5)缓存机制比较
Hibernate 的二级缓存配置在 SessionFactory 生成配置文件中进行详细配置,然后再在具体的表对象映射中配置那种缓存。
MyBatis 的二级缓存配置都是在每个具体的表对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓冲机制,并且 MyBatis 可以在命名空间中共享相同的缓存配置和实例,通过 Cache-ref 来实现。
两者比较,因为 Hibernate 对查询对象有着良好的管理机制,用户无需关心 SQL,所以在使用二级缓存时如果出现脏数据,系统会报出错误提示。 而 MyBatis 在这一方面使用二级缓存时需要特别小心,如果不能完全去顶数据更新操作的波及范围,避免 cache 的盲目使用,否则,脏数据的出现会给系统的正常运行带来很大的隐患。
mybatis 是如何工作的?
一、Mybatis 工作原理图
mybatis 原理图如下所示:
二、工作原理解析
mybatis 应用程序通过 SqlSessionFactoryBuilder 从 mybatis-config.xml 配置文件(也可以用 Java 文件配置的方式,需要添加@Configuration)来构建 SqlSessionFactory(SqlSessionFactory 是线程安全的);
然后,SqlSessionFactory 的实例直接开启一个 SqlSession,再通过 SqlSession 实例获得 Mapper 对象并运行 Mapper 映射的 SQL 语句,完成对数据库的 CRUD 和事务提交,之后关闭 SqlSession。说明:SqlSession 是单线程对象,因为它是非线程安全的,是持久化操作的独享对象,类似 jdbc 中的 Connection,底层就封装了 jdbc 连接。
详细流程如下:
(1)、加载 mybatis 全局配置文件(数据源、mapper 映射文件等),解析配置文件,MyBatis 基于 XML 配置文件生成 Configuration,和一个个 MappedStatement(包括了参数映射配置、动态 SQL 语句、结果映射配置),其对应着标签项。
(2)、SqlSessionFactoryBuilder 通过 Configuration 对象生成 SqlSessionFactory,用来开启 SqlSession。
(3)、SqlSession 对象完成和数据库的交互:
a、用户程序调用 mybatis 接口层 api(即 Mapper 接口中的方法)
b、SqlSession 通过调用 api 的 Statement ID 找到对应的 MappedStatement 对象
c、通过 Executor(负责动态 SQL 的生成和查询缓存的维护)将 MappedStatement对象进行解析,sql 参数转化、动态 sql 拼接,生成 jdbc Statement 对象
d、JDBC 执行 sql。
e、借助 MappedStatement 中的结果映射关系,将返回结果转化成 HashMap、JavaBean 等存储结构并返回。
Hibernate 对象有几个状态值?
Transient 瞬时 :对象刚 new 出来,还没设 id,设了其他值。
Persistent 持久:调用了 save()、saveOrUpdate(),就变成 Persistent,有 id
Detached 脱管 : 当 session close()完之后,变成 Detached。
简述 Springmvc 的流程;
spring 工作的流程
流程如下:(1)用户发起请求到前端控制器(DispatcherServlet),该控制器会过滤出哪些请求可以访问 Servlet、哪些不能访问。就是 url-pattern 的作用,并且会加载springmvc.xml 配置文件。
(2)前端控制器会找到处理器映射器(HandlerMapping),通过 HandlerMapping完成 url 到 controller 映射的组件,简单来说,就是将在 springmvc.xml 中配置的或者注解的 url 与对应的处理类找到并进行存储,用 map
(3)HandlerMapping 有了映射关系,并且找到 url 对应的处理器,HandlerMapping就会将其处理器(Handler)返回,在返回前,会加上很多拦截器。
(4)DispatcherServlet 拿到 Handler 后,找到 HandlerAdapter(处理器适配器),通过它来访问处理器,并执行处理器。
(5)执行处理器
(6)处理器会返回一个 ModelAndView 对象给 HandlerAdapter
(7) 通 过 HandlerAdapter 将 ModelAndView 对 象 返 回 给 前 端 控 制 器(DispatcherServlet)
(8)前端控制器请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),其实就是将 ModelAndView 对象中存放视图的名称进行查找,找到对应的页面形成视图对象
(9)返回视图对象到前端控制器。
(10)视图渲染,就是将 ModelAndView 对象中的数据放到 request 域中,用来让页面加载数据的。
(11)通过第 8 步,通过名称找到了对应的页面,通过第 10 步,request 域中有了所需要的数据,那么就能够进行视图渲染了。最后将其返回即可。
Springmvc 和 Springboot 有什么区别?
Spring MVC 是基于 Spring 的一个 MVC 框架 ;
Spring Boot 是基于 Spring4 的条件注册的一套快速开发整合包。
Springboot 为什么配置简单?(即它自动做了什么操作才能简化程序员的操作)
主要是使用了 spring3 之后提供的注解,来代替 xml 文件的配置,最核心的是以下两个注解
@Configuration,标注在类上,相当于定义一个配置类,一份 spring 的配置文件
@Bean,类似于 spring 配置文件中的通过这两个注解就可以用 java 代码的方式来完成相关 spring 配置
持久层设计要考虑的问题有哪些?请谈一下你用过的持久层框架都有哪些?
"持久"就是将数据保存到可掉电式存储设备中以便今后使用,简单的说,就是将内存中的数据保存到关系型数据库、文件系统、消息队列等提供持久化支持的设备中。持久层就是系统中专注于实现数据持久化的相对独立的层面。
持久层设计的目标包括:
数据存储逻辑的分离,提供抽象化的数据访问接口。
数据访问底层实现的分离,可以在不修改代码的情况下切换底层实现。
资源管理和调度的分离,在数据访问层实现统一的资源调度(如缓存机制)。
数据抽象,提供更面向对象的数据操作。
持久层框架有: Hibernate、MyBatis、TopLink、 Guzz、 jOOQ、 Spring Data、ActiveJDBC
需要更多技术文档可以在后台私信【学习】