为什么使用Spring(优缺点)
spring容器创建对象的时机
Spring的常用注解解释
Spring MVC的常用注解解释
Mybatis的常用标签或者注解用过哪些
spring bean 的生命周期【~】
Spring事务(ACID,隔离级别,事务传播机制)
IOC底层实现原理【~】
AOP底层实现原理【~】
AOP详解
Spring MVC 运行流程(好)
什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)
BeanFactory和ApplicationContext区别
Mybatis中的#{}跟${}有什么区别。
从架构设计的角度,可以将 MyBatis 分为哪几层?每层都有哪些主要模块?
spring 常用的注入方式有哪些?
spring bean 的作用域
说一下 spring 的事务隔离?
@RequestMapping @Autowired 的作用是什么?
说一下 hibernate 的缓存机制?
分页插件的实现原理是什么?MyBatis 逻辑分页和物理分页的区别是什么
说一下 MyBatis 的一级缓存和二级缓存
MyBatists的resultType和resultmap的区别
MyBatists的好处?
MyBatis 与 Hibernate 的区别?
使用 MyBatis 的 mapper 接口调用时有哪些要求
BeanFactory
ApplicationContext
SpringBoot常用注解
谈谈你对SpringBoot的理解
讲一下SpringBoot的四大核心功能
为什么使用Spring(优缺点)
①、方便解耦,简化开发(IOC:通过Spring提供的IoC容器,我们可以将对象之间的依赖关系交由Spring进行控制,避免硬编码所造成的过度程序耦合。)
②、AOP编程的支持(通过Spring提供的AOP功能,方便进行面向切面的编程)
③、声明式事务的支持(可以从单调烦闷的事务管理代码中解脱出来,)
④、方便程序的测试(Spring对Junit4支持,可以通过注解方便的测试Spring程序。)
⑤、方便集成各种优秀框架(Spring不排斥各种优秀的开源框架如Struts,Hibernate)
spring容器创建对象的时机
第一种:默认情况下,启动 spring 容器便创建对象(遇到bean便创建对象)
第二种:在spring的配置文件bean中有一个属性 lazy-init=“default/true/false”
①、如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况)
②、如果lazy-init为"true",在context.getBean时才要创建对象
Spring的常用注解解释
第一步:在 applicationContext.xml 中引入命名空间 引入的命名空间,简单来说就是用来约束xml文件格式的。
第二步:在 applicationContext.xml 文件中引入注解扫描器<context:component-scan base-package=“com.ys.annotation”></context:component-scan>
@Component(@Repository :dao层 @Service:service层 @Controller:web层 功能一样)
@Component
public class Person {}
等价于
@Component(“p”)
public class Person {}
等价于
@Resource 注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 通过 @Resource 的使用来消除 set ,get方法。
@Autowired功能和注解 @Resource 一样,可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。只不过注解@Resource 是按照名称来进行装配,而@Autowired 则是按照类型来进行装配。(它首先会根据类型去匹配,多个则按名称,空则会抛出异常。法二:@Autowired 和 @Qualifier(“名称”) 配合使用)
@Qualifier:将@Qualifier注解和@Autowire注解结合使用,指定需要装配的确切的bean。
@Required:表明bean的属性必须在配置的时候设置.
@Configuration 声明当前类是一个配置类 @Configuation等价于
@Bean 注解的方法将会实例化、配置和初始化一个新对象,这个对象将由 Spring的 IoC 容器来管理, 作用与 元素类似
不同点:实现原理不同,@Configuration基于CGlib代理实现,@Component基于反射实现;
Spring MVC的常用注解解释
@Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象。
@RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
@PathVariable用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数
@RequestMapping(value="/product/{productId}",method = RequestMethod.GET)
public String getProduct(@PathVariable(“productId”) String productId)
@Responsebody 注解表示该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,一般在异步获取数据时使用;
在使用 @RequestMapping 后,返回值通常解析为跳转路径,加上 @Responsebody 后返回结果不会被解析为跳转路径,而是直接写入HTTP 响应正文中。例如,异步获取 json 数据,加上 @Responsebody 注解后,就会直接返回 json 数据。
@RequestParam 在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter(“name”),另外一种是用注解@RequestParam直接获取。这里主要讲这个注解 。 spring会自动根据参数名字封装进入,我们可以直接拿这个参数名来用
- @RequestMapping(“testRequestParam”) 参数同名
- public String filesUpload(@RequestParam String inputStr, HttpServletRequest request) {
int inputInt = Integer.valueOf(request.getParameter(“inputInt”));
前 -
参数inputStr:<input type="text" name="inputStr">
-
参数intputInt:<input type="text" name="inputInt">
1、可以对传入参数指定参数名
@RequestParam(value=“aa”) String inputStr
2、可以通过required=false或者true来要求@RequestParam配置的前端参数是否一定要传
public String filesUpload(@RequestParam(value=“aa”, required=true) String inputStr, HttpServletRequest request)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Mybatis的常用标签或者注解用过哪些
MyBatis 的强大特性之一便是它的动态 SQL
标签:
spring bean 的生命周期
1.Spring 容器根据配置中的 bean 定义中实例化 bean。
2. Spring 使用依赖注入填充所有属性,如 bean 中所定义的配置。
3. 如果 bean 实现 BeanNameAware 接口,则工厂通过传递 bean 的 ID 来调用 setBeanName()。
4. 如果 bean 实现 BeanFactoryAware 接口,工厂通过传递自身的实例来调用 setBeanFactory()。
5. 如果存在与 bean 关联的任何 BeanPostProcessors,则调用 postProcessBeforeInitialization() 方法。
6. 如果为 bean 指定了 init 方法( 的 init-method 属性),那么将调用它。
7. 最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调用 postProcessAfterInitialization() 方法。
8. 如果 bean 实现 DisposableBean 接口,当 spring 容器关闭时,会调用 destory()。
9. 如果为 bean 指定了 destroy 方法( 的 destroy-method 属性),那么将调用它。
Spring事务(ACID,隔离级别,事务传播机制)
PlatformTransactionManager:Spring事务管理器
TransactionStatus:事务状态,提供简单的控制事务执行和查询事务状态的方法
TransactionDefinition: 定义了一些基本的事务属性
实现原理:
Spring并不直接管理事务,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器。也就是将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。
ACID
①、原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
②、一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
③、隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
④、持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中
事务传播机制:当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。
①、PROPAGATION_REQUIRED :required , 必须。默认值,A如果有事务,B将使用该事务;如果A没有事务,B将创建一个新的事务。
②、PROPAGATION_SUPPORTS:supports ,支持。A如果有事务,B将使用该事务;如果A没有事务,B将以非事务执行。
③、PROPAGATION_MANDATORY:mandatory ,强制。A如果有事务,B将使用该事务;如果A没有事务,B将抛异常。
④、PROPAGATION_REQUIRES_NEW :requires_new,必须新的。如果A有事务,将A的事务挂起,B创建一个新的事务;如果A没有事务,B创建一个新的事务。
⑤、PROPAGATION_NOT_SUPPORTED :not_supported ,不支持。如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B将以非事务执行。
⑥、PROPAGATION_NEVER :never,从不。如果A有事务,B将抛异常;如果A没有事务,B将以非事务执行。
⑦、PROPAGATION_NESTED :nested ,嵌套。A和B底层采用保存点机制,形成嵌套事务。
隔离级别:定义了一个事务可能受其他并发事务影响的程度。(与数据库隔离级别相似) TransactionDefinition.class 中也分别用常量 -1,0,1,2,4,8表示
①、ISOLATION_DEFAULT:使用后端数据库默认的隔离级别-1
②、ISOLATION_READ_UNCOMMITTED:(读未提交)最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读0
③、ISOLATION_READ_COMMITTED:(读已提交)允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生1
④、ISOLATION_REPEATABLE_READ:(可重复读)对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生2
⑤、ISOLATION_SERIALIZABLE:(序列化)最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的4
Spring支持的事务管理类型:1)编程式事务管理 2)声明式事务管理
声明式事务管理要优于编程式事务管理,灵活
声明式事务
①、在applicationContext.xml 配置事务管理器,将并事务管理器交予spring
②、在目标类或目标方法添加注解即可 @Transactional(如果在类上添加,则说明类中的所有方法都添加事务,如果在方法上添加,则只有该方法具有事务。)
@Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)
@Service(“accountService”)
public class AccountServiceImpl implements AccountService{
1
2
3
IOC底层实现原理
概念:
IOC 是面向对象编程中的一种设计原则,IOC理论提出的观点大体是这样的:借助于“第三方”实现具有依赖关系的对象之间的解耦。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。 是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方。
实现原理:
它是通过反射机制+工厂模式实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。
控制反转就是:获得依赖对象的方式反转了。`
1、依赖注入发生的时间
(1).用户第一次通过getBean方法向IoC容索要Bean时,IoC容器触发依赖注入。
(2).当用户在Bean定义资源中为元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入。
2.依赖注入实现在以下两个方法中:
(1).createBeanInstance:生成Bean所包含的java对象实例。
(2).populateBean :对Bean属性的依赖注入进行处理。
AOP底层实现原理
概念
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。 而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。 简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。
AOP的实现
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
动态代理:提供一个基础的接口,作为被调用类型(com.mycorp.HelloImpl)和代理类之间的统一入口,如 com.mycorp.Hello。
实现InvocationHandler,对代理对象方法的调用,会被分派到其 invoke 方法来真正实现动作。
通过 Proxy 类,调用其 newProxyInstance 方法,生成一个实现了相应基础接口的代理类实例,
Java在JDK1.3后引入的动态代理机制,使我们可以在运行期动态的创建代理类。使用动态代理实现AOP需要有四个角色:被代理的类,被代理类的接口,织入器,和InvocationHandler,而织入器使用接口反射机制生成一个代理类,然后在这个代理类中织入代码。被代理的类是AOP里所说的目标,InvocationHandler是切面,它包含了Advice和Pointcut。
如何使用Spring AOP
可以通过配置文件或者编程的方式来使用Spring AOP。 配置可以通过xml文件来进行,大概有四种方式:
1)配置ProxyFactoryBean,显式地设置advisors, advice, target等
2)配置AutoProxyCreator,这种方式下,还是如以前一样使用定义的bean,但是从容器中获得的其实已经是代理对象
3)通过aop:config来配置
4)通aop:aspectj-autoproxy过来配置,使用AspectJ的注解来标识通知及切入点
Spring AOP的实现
如何生成代理类:
Spring提供了两种方式来生成代理对象: JDKProxy和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK动态代理技术,否则使用Cglib来生成代理
切面是如何织入的?
InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。
AOP详解:
AOP(Aspect-OrientedProgramming,面向方面编程)它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。便于减少系统的重复代码,降低模块间的耦合度,核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。
性能监控,在方法调用前后记录调用时间,方法执行太长或超时报警。
缓存代理,缓存某方法的返回值,下次执行该方法时,直接从缓存里获取。
软件破解,使用AOP修改软件的验证类的判断逻辑。
记录日志,在方法执行前后记录系统日志。
工作流系统,工作流系统需要将业务代码和流程引擎代码混合在一起执行,那么我们可以使用AOP将其分离,并动态挂接业务。
权限验证,方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉。
AOP能干什么,也是AOP带来的好处
1:降低模块的耦合度
2:使系统容易扩展
3:设计决定的迟绑定:使用AOP,设计师可以推迟为将来的需求作决定,因为它
可以把这种需求作为独立的方面很容易的实现。
4:更好的代码复用性
AOP基本概念
3、aop编程
3.1 导入命名空间
3.2 使用 aop:config进行配置
proxy-target-class=“true” 声明时使用cglib代理
如果不声明,Spring 会自动选择cglib代理还是JDK动态代理
aop:pointcut 切入点 ,从目标对象获得具体方法
aop:advisor 特殊的切面,只有一个通知 和 一个切入点
advice-ref 通知引用
pointcut-ref 切入点引用
3.3 切入点表达式
execution(* com.ys.aop..(…))
选择方法 返回值任意 包 类名任意 方法名任意 参数任意
1
2
3
4
5
6
7
8
9
10
11
12
连接点(Joinpoint):
表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,Spring只支持方法执行连接点,在AOP中表示为“在哪里做”;
切入点(Pointcut):
选择一组相关连接点的模式,即可以认为连接点的集合,Spring支持perl5正则表达式和AspectJ切入点模式,Spring默认使用AspectJ语法,在AOP中表示为“在哪里做的集合”;
语法:execution(修饰符 返回值 包.类.方法名(参数) throws异常)
<aop:pointcut expression=“execution(* com.ys.aop..(…))” id=“myPointCut”/>
1
增强(Advice):或称为增强
在连接点上执行的行为,增强提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置增强(before advice)、后置增强 (after advice)、环绕增强 (around advice),在Spring中通过代理模式实现AOP,并通过拦截器模式以环绕连接点的拦截器链织入增强 ;在AOP中表示为“做什么”;
方面/切面(Aspect):
横切关注点的模块化,比如上边提到的日志组件。可以认为是增强、引入和切入点的组合;在Spring中可以使用Schema和@AspectJ方式进行组织实现;在AOP中表示为“在哪里做和做什么集合”;
目标对象(Target Object):
需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被增强的对象,从而也可称为“被增强对象”;由于Spring AOP 通过代理模式实现,从而这个对象永远是被代理对象,在AOP中表示为“对谁做”;
AOP代理(AOP Proxy):
AOP框架使用代理模式创建的对象,从而实现在连接点处插入增强(即应用切面),就是通过代理来对目标对象应用切面。在Spring中,AOP代理可以用JDK动态代理或CGLIB代理实现,而通过拦截器模型应用切面。
织入(Weaving):
织入是一个过程,是将切面应用到目标对象从而创建出AOP代理对象的过程,织入可以在编译期、类装载期、运行期(AOP三种织入方式)进行。
引入(inter-type declaration):
也称为内部类型声明,为已有的类添加额外新的字段或方法,Spring允许引入新的接口(必须对应一个实现)到所有被代理对象(目标对象), 在AOP中表示为“做什么(新增什么)”;
AOP的Advice类型
<aop:around method="" pointcut-ref=""/>
1
前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。 在方法前切入
正常返回通知[After returning advice]:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行。
异常返回通知[After throwing advice]:在连接点抛出异常后执行。
返回通知[After (finally) advice]:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容。
环绕通知[Around advice]:环绕通知围绕在连接点前后,比如一个方法调用的前后。这是最强大的通知类型,能在方法调用前后自定义一些操作。环绕通知还需要负责决定是继续处理join point(调用ProceedingJoinPoint的proceed方法)还是中断执行。
包围一个连接点的增强,如方法调用。这是最强大的一种增强类型。 环绕增强可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。
动态字节码生成 (Cglib)
使用动态字节码生成技术实现AOP原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口。
Cglib是一个强大的,高性能的Code生成类库,它可以在运行期间扩展Java类和实现Java接口,它封装了Asm,所以使用Cglib前需要引入Asm的jar。
Spring默认采取的动态代理机制实现AOP,当动态代理不可用时(代理类无接口)会使用CGlib机制。但Spring的AOP有一定的缺点,第一个只能对方法进行切入,不能对接口,字段,静态代码块进行切入(切入接口的某个方法,则该接口下所有实现类的该方法将被切入)。第二个同类中的互相调用方法将不会使用代理类。因为要使用代理类必须从Spring容器中获取Bean。第三个性能不是最好的,从3.3章节我们得知使用自定义类加载器,性能要优于动态代理和CGlib。
https://www.cnblogs.com/ysocean/p/7617620.html
Spring MVC 运行流程(好
用户发起请求到前端控制器(Controller)
前端控制器没有处理业务逻辑的能力,需要找到具体的模型对象处理(Handler),到处理器映射器(HandlerMapping)中查找Handler对象(Model)。
HandlerMapping返回执行链,包含了2部分内容: ① Handler对象、② 拦截器数组
前端处理器通过处理器适配器包装后执行Handler对象。
处理业务逻辑。
Handler处理完业务逻辑,返回ModelAndView对象,其中view是视图名称,不是真正的视图对象。
将ModelAndView返回给前端控制器。
视图解析器(ViewResolver)返回真正的视图对象(View)。
(此时前端控制器中既有视图又有Model对象数据)前端控制器根据模型数据和视图对象,进行视图渲染。
返回渲染后的视图(html/json/xml)返回。
11。给用户产生响应。
1). 用户发请求–>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制。
2).DispatcherServlet–>HandlerMapping,HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器,多个HandlerInterceptor拦截器)。
3).DispatcherServlet–>HandlerAdapter,HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器。
4).HandlerAdapter–>处理器功能处理方法的调用,HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理,并返回一个ModelAndView对象(包含模型数据,逻辑视图名)
5).ModelAndView的逻辑视图名–>ViewResolver,ViewResoler将把逻辑视图名解析为具体的View。
6).View–>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构
7).返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户。
什么是控制反转(Inversion of Control)与依赖注入(Dependency Injection)
控制反转:是指将创建对象的功能交给Spring容器,在我们需要使用对象的时候不需要自己创建,可以直接从容器中获取。
依赖注入:动态的向某个对象提供它所依赖的其他对象。
BeanFactory和ApplicationContext区别
1.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。 而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。
2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。
3. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能: a. 国际化支持, b. 资源访问, 如URL和文件 c. 事件传递
Mybatis中的#{}跟${}有什么区别
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”, 如果传入的值是id,则解析成的sql为order by “id”.
$将传入的数据直接显示生成在sql中。如:order by useriduser_iduser
i
d,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
#方式能够很大程度防止sql注入。 方式无法防止Sql注入3.方式无法防止Sql注入3.方式无法防止Sql注入3.方式一般用于传入数据库对象,例如传入表名. 一般能用#的就别用.MyBatis排序时使用orderby动态参数时需要注意,用.MyBatis排序时使用order by 动态参数时需要注意,用.MyBatis排序时使用orderby动态参数时需要注意,用而不是# ORDER BY ${columnName} 这里MyBatis不会修改或转义字符串。
使用#{}格式的语法在mybatis中使用Preparement语句来安全的设置值,
不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:
ORDER BY ${columnName}
此时MyBatis 不会修改或转义字符串。
从架构设计的角度,可以将 MyBatis 分为哪几层?每层都有哪些主要模块?
mybatis架构自下而上分为基础支撑层、数据处理层、API接口层这三层。
基础支撑层,主要是用来做连接管理、事务管理、配置加载、缓存管理等最基础组件,为上层提供最基础的支撑。
数据处理层,主要是用来做参数映射、sql解析、sql执行、结果映射等处理,可以理解为请求到达,完成一次数据库操作的流程。
API接口层,主要对外提供API,提供诸如数据的增删改查、获取配置等接口。
spring 常用的注入方式有哪些?
setter 属性注入
构造方法注入
注解方式注入
spring bean 的作用域:
applicationContext.xml 文件中配置:
1
singleton:spring ioc 容器中只存在一个 bean 实例,bean 以单例模式存在,是系统默认值;
prototype:每次从容器调用 bean 时都会创建一个新的示例,既每次 getBean()相当于执行 new Bean()操作;
在单例模式下,启动 spring 容器,便会创建对象;在多例模式下,启动容器并不会创建对象,获得 bean 的时候才会创建对象
Web 环境下的作用域:
request:每次 http 请求都会创建一个 bean;
session:同一个 http session 共享一个 bean 实例;
global-session:用于 portlet 容器,因为每个 portlet 有单独的 session,globalsession 提供一个全局性的 http session。
注意: 使用 prototype 作用域需要慎重的思考,因为频繁创建和销毁 bean 会带来很大的性能开销。
说一下 spring 的事务隔离?
spring 有五大隔离级别,默认值为 ISOLATION_DEFAULT(使用数据库的设置),其他四个隔离级别和数据库的隔离级别一致:
ISOLATION_DEFAULT:用底层数据库的设置隔离级别,数据库设置的是什么我就用什么;
ISOLATIONREADUNCOMMITTED:未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读);
ISOLATIONREADCOMMITTED:提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读),SQL server 的默认级别;
ISOLATIONREPEATABLEREAD:可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读),MySQL 的默认级别;
ISOLATION_SERIALIZABLE:序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读。
@RequestMapping 的作用是什么?
将 http 请求映射到相应的类/方法上。
@Autowired 的作用是什么?
@Autowired 它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作,通过@Autowired 的使用来消除 set/get 方法。
说一下 hibernate 的缓存机制?
hibernate 常用的缓存有一级缓存和二级缓存:
一级缓存:也叫 Session 缓存,只在 Session 作用范围内有效,不需要用户干涉,由 hibernate 自身维护,可以通过:evict(object)清除 object 的缓存;clear()清除一级缓存中的所有缓存;flush()刷出缓存;
二级缓存:应用级别的缓存,在所有 Session 中都有效,支持配置第三方的缓存,如:EhCache。
分页插件的实现原理是什么?
Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页,可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。 Mybatis 使用 JDK 的动态代理,在插件的拦截方法内拦截待执行的 SQL,然后重写 SQL,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
MyBatis 逻辑分页和物理分页的区别是什么?
逻辑分页是一次性查询很多数据,然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。
物理分页是从数据库查询指定条数的数据,弥补了一次性全部查出的所有数据的种种缺点,比如需要大量的内存,对数据库查询压力较大等问题。
说一下 MyBatis 的一级缓存和二级缓存?
https://www.cnblogs.com/ysocean/tag/MyBatis详解系列/
一级缓存:基于 PerpetualCache 的 HashMap 本地缓存,它的声明周期是和 SQLSession 一致的,有多个 SQLSession 或者分布式的环境中数据库操作,可能会出现脏数据。当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认一级缓存是开启的。
二级缓存:也是基于 PerpetualCache 的 HashMap 本地缓存,不同在于其存储作用域为 Mapper 级别的,如果多个SQLSession之间需要共享缓存,则需要使用到二级缓存,并且二级缓存可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态)。
MyBatists的 resultType和resultmap的区别
接下来说说有关Mapper.xml配置文件中查询标签中关于返回值类型resultType与resultMap
1) resultType是直接表示返回类型的,而resultMap 指的是定义好了的id的,是定义好的resyltType的引用,但是resultType跟resultMap不能同时存在。
2) 当提供的返回类型属性是resultType时,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当提供的返回类型属性是resultType的时候,MyBatis会自动的给把对应的值赋给resultType所指定对象的属性。
3)resultType对应的是java对象中的属性,大小写不敏感, 如果放的是java.lang.Map,key是查询语句的列名,value是查询的值,大小写敏感;resultMap对应的是对已经定义好了id的resultType的引用,key是查询语句的列名,value是查询的值,大小写敏感;
4)使用resultType的时候,要保证结果集的列名与java对象的属性相同,而resultMap则不用, 而且resultMap可以用typeHander转换
5) resultMap 元素,它是 MyBatis 中最重要最强大的元素,它能提供级联查询,缓存等功能。
https://blog.csdn.net/leo3070/article/details/77899574
返回单个实例
execute, executeQuery, executeUpdate 的区别
Statement 的 execute(String query)方法用来执行任意的 SQL 查询. 如果查询的结果是一个 ResultSet,这个方法就返回 true。
Statement 的 executeQuery(String query)接口用来执行 select 查询,并且返 回 ResultSet
Statement 的 executeUpdate(String query) 方 法 用 来 执 行 insert 或 者 update/delete(DML)语句,或者 什么也不返回
只有当你不确定是什么语句的时候才应该使用 execute()方法,否则应该使用executeQuery 或者 executeUpdate 方法。
MyBatists的好处?
1) 避免创建、释放频繁造成系统资源浪费 :在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2) 将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3) Mybatis 自动将 java 对象映射至 sql 语句。因为向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需
要和参数一一对应
4) Mybatis 自动将 sql 执行结果映射至 java 对象。因为 对结果集解析麻烦, sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记
录封装成 pojo 对象解析比较方便
MyBatis 与 Hibernate 的区别?
1) Mybatis 学习门槛低,简单易学,程序员直接编写原生态 sql
2) mybatis 可以通过 XML 或注解方式灵活配置要运行的 sql 语句,并将 java 对象和 sql 语句映射生成最终执行的 sql,最后将 sql 执行的结果再映射生成 java 对象。
3) MyBatis灵活度高,适合需求变化频繁
使用 MyBatis 的 mapper 接口调用时有哪些要求
① Mapper 接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
② Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类
型相同
③ Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相
同 ④
Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。
SpringMVC 怎么样设定重定向和转发的?
在返回值前面加”forward:” 就可以让结果转发。 ”forward:user.do?name=method4” 在返回值前面加”redirect:”就可以让返回值重定向,
如果在拦截请求中,我想拦截 get 方式提交的方法,怎么配置? 可以在@RequestMapping 注解里面加上 method=RequestMethod.GET
SpringMvc 里面拦截器是怎么写的?
一种是实现接口,另外一种是继承适配器类,然后在 SpringMvc 的配置文件中配置
拦截器即可:
mvc:interceptor
<mvc:mapping path="/modelMap.do" />
</mvc:interceptor>
1
2
3
4
5
BeanFactory
在org.springframework.beans和org.springframework.context包是Spring框架的IoC容器的基础。该 BeanFactory 接口提供了一种能够管理任何类型对象的高级配置机制
Bean工厂实现应尽可能支持标准bean生命周期接口。完整的初始化方法及其标准顺序是:
- BeanNameAware的 setBeanName
- BeanClassLoaderAware的 setBeanClassLoader
- 实现BeanFactoryAware的 setBeanFactory
- EnvironmentAware的 setEnvironment
- EmbeddedValueResolverAware的 setEmbeddedValueResolver
- ResourceLoaderAware setResourceLoader (仅在应用程序上下文中运行时适用)
- ApplicationEventPublisherAware setApplicationEventPublisher (仅在应用程序上下文中运行时适用)
- MessageSourceAware setMessageSource (仅在应用程序上下文中运行时适用)
- ApplicationContextAware setApplicationContext (仅在应用程序上下文中运行时适用)
- ServletContextAware setServletContext (仅在Web应用程序上下文中运行时适用)
- postProcessBeforeInitialization BeanPostProcessors的方法
- InitializingBean的 afterPropertiesSet
- 自定义init方法定义
- postProcessAfterInitialization BeanPostProcessors的方法
关闭bean工厂时,以下生命周期方法适用:
- postProcessBeforeDestruction DestructionAwareBeanPostProcessors的方法
- DisposableBean的的 destroy
- 自定义销毁方法定义
ApplicationContext
在org.springframework.beans和org.springframework.context包是Spring框架的IoC容器的基础。该 BeanFactory 接口提供了一种能够管理任何类型对象的高级配置机制。 ApplicationContext 是一个BeanFactory的拓展。它补充说:
1)更容易与Spring的AOP功能集成
2)消息资源处理(用于国际化)
3)活动出版
4)特定WebApplicationContext 于应用程序层的上下文,例如在Web应用程序中使用的上下文。
ApplicationContext提供:
- Bean工厂方法,用于访问应用程序组件 继承自ListableBeanFactory。
- 以通用方式加载文件资源的能力。继承自ResourceLoader接口。
- 将事件发布到已注册的侦听器的功能。继承自ApplicationEventPublisher接口。
- 解决消息,支持国际化的能力。继承自MessageSource接口。
- 从父上下文继承。后代上下文中的定义始终优先。这意味着,例如,整个Web应用程序可以使用单个父上下文,而每个servlet都有自己的子上下文,该上下文独立于任何其他servlet的子上下文。
除了标准的BeanFactory 生命周期的能力,ApplicationContext实现检测和调用 ApplicationContextAware豆类以及ResourceLoaderAware, ApplicationEventPublisherAware和MessageSourceAware 类。
该org.springframework.context.ApplicationContext接口代表Spring IoC容器,负责实例化,配置和组装bean。容器通过读取配置元数据获取有关要实例化,配置和组装的对象的指令。配置元数据以XML,Java注释或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖性。。在独立应用程序中,通常会创建一个ClassPathXmlApplicationContext 或的实例 FileSystemXmlApplicationContext。
公共类ClassPathXmlApplicationContext : 独立的XML应用程序上下文,从类路径获取上下文定义文件,将普通路径解释为包含包路径的类路径资源名称(例如“mypackage / myresource.txt”)。适用于测试工具以及JAR中嵌入的应用程序上下文。 如“/myfiles/context.xml”或Ant样式模式,如“/myfiles/*-context.xml”。
SpringBoot常用注解
@SpringBootApplication: 包含@Configuration、@EnableAutoConfiguration、@ComponentScan@RestController: 用于标注控制层组件,包含@Controller和@ResponseBody
@Autowired
@Qualifier
@RequestMapping
谈谈你对SpringBoot的理解
Spring Boot开发始于 2013 年,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。
spring boot 是微服务框架的起点,他简化了开发过程,配置过程、部署过程、监控过程。
它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了很多的框架,同时将其他技术同spring结合起来。通过SpringBoot我们可以很快的搭建一套web项目。
不足:
SpringBoot还需要与外围的框架进行集成1)认证鉴定方面2)监控方面等
讲一下SpringBoot的四大核心功能
起步依赖机制:通过起步依赖机制(Starter),简化jar包的引用,解决jar版本冲突问题。
自动配置:可以实现简单配置,甚至是零配置,就能搭建整套框架。
StringBoot CLI(命令行界面):一种命令工具。
Actuator:是SpringBoot的程序监控器,可监控Spring应用程序上下文中的Bean、查看自动配置决策、Controller映射、线程活动、应用程序健康状况等。
————————————————
版权声明:本文为CSDN博主「睶先森」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Butterfly_resting/article/details/89670153