spring的面试题
spring是什么?
是一个轻量级的开源的容器框架,用来装Javabean(Java对象的),中间层框架,起一个连接作用,常用与dao层框架整合使用,是企业开发更方便,快捷。
spring是一个轻量级的控制反转(ioc)和面向切面(aop)的容器框架
谈谈你对aop的理解?
AOP(Aspect-Oriented Programming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。
而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。
使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”
描述一下Spring AOP
Spring AOP(Aspect Oriented Programming,面向切面编程)是OOPs(面向对象编程)的补充,它也提供了模块化。在面向对象编程中,关键的单元是对象,AOP的关键单元是切面,或者说关注点(可以简单地理解为你程序中的独立模块)。一些切面可能有集中的代码,但是有些可能被分散或者混杂在一起,例如日志或者事务。这些分散的切面被称为横切关注点。一个横切关注点是一个可以影响到整个应用的关注点,而且应该被尽量地集中到代码的一个地方,例如事务管理、权限、日志、安全等。
AOP让你可以使用简单可插拔的配置,在实际逻辑执行之前、之后或周围动态添加横切关注点。这让代码在当下和将来都变得易于维护。如果你是使用XML来使用切面的话,要添加或删除关注点,你不用重新编译完整的源代码,而仅仅需要修改配置文件就可以了。
Spring AOP通过以下两种方式来使用。但是最广泛使用的方式是Spring AspectJ 注解风格(Spring AspectJ Annotation Style)
- 使用AspectJ 注解风格
- 使用Spring XML 配置风格
在Spring AOP中关注点和横切关注点有什么不同?
关注点是我们想在应用的模块中实现的行为。关注点可以被定义为:我们想实现以解决特定业务问题的方法。比如,在所有电子商务应用中,不同的关注点(或者模块)可能是库存管理、航运管理、用户管理等。
横切关注点是贯穿整个应用程序的关注点。像日志、安全和数据转换,它们在应用的每一个模块都是必须的,所以他们是一种横切关注点。
动态代理?
jdk1.5中提供,利用反射。实现InvocationHandler接口。
JDK动态代理:利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强。采用的是继承的方式。不细说,看使用
CGlib动态代理:利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
区别:JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类。
总结:1.JDK代理使用的是反射机制实现aop的动态代理,CGLIB代理使用字节码处理框架asm,通过修改字节码生成子类。所以jdk动态代理的方式创建代理对象效率较高,执行效率较低,cglib创建效率较低,执行效率高;2.JDK动态代理机制是委托机制,具体说动态实现接口类,在动态生成的实现类里面委托hanlder去调用原始实现类方法,CGLIB则使用的继承机制,具体说被代理类和代理类是继承关系,所以代理类是可以赋值给被代理类的,如果被代理类有接口,那么代理类也可以赋值给接口。
谈谈你对ioc的理解?
ioc本身是一个容器:可以理解成一个map(key,value),里面存在着各种对象(xml配置bean节点,注解注入的bean,),在项目启动时会读取配置或者扫描注解,通过反射创建对象放到map中,在代码中需要用到里面的对象时,再通过DI注入对象的的属性值
控制反转:
在没有引入ioc容器之前,对象A依赖对象B,在A对象初始化或者运行时,自己必须主动去创建B对象,控制权在自己的手上
引入ioc容器之后,全部对象的控制权都交给了ioc容器,当对象A需要用到B对象的时候,ioc容器会主动去创建一个对象B注入到A需要的地方,B对象的创建权利交给了ioc容器,这就是控制反转
依赖注入:
依赖注入是实现ioc的方法,ioc容器在运行期间,动态的将某种依赖关系注入到对象之中。ioc容器主动注入了使用的对象,和使用所需要依赖的对象
beanFactory和applicationcontext的区别
1.applicationcontext是beanFactory的子接口,所以applicationcontext提供了更完整的功能。
2.applicationcontext继承了messagesource类,因此支持国际化,统一的资源文件访问方式,提供了在监听器中注册bean的事件,可用同时加载多个配置文件,
beanFactory采用的延迟加载注入bean,当调用bean的时候才初始化,所以我们不能第一时间发现配置文件中是否存在问题。
applicationcontext采用的是立即加载 ,有利于检查配置文件是否有问题,缺点是启动时加载大量的bean,会占用内存空间,
springbean的生命周期面试?
1.解析类得到beandefinition
2.如果有多个构造方法,则要推断构造方法
3.确定好构造方法后,进行实例化得到一个对象
4.对对象中加了@Autowired注解的属性进行属性填充
5.回调aware方法,比如beanNameAware,beanFactoryAware
6.调用beanpostprocessor的初始化前方法
7.调用初始化方法
8.调用beanpostprocessor的初始化后方法,这里会进行aop
9.如果当前创建的bean是单例则会把bean方法单例池
10.bean就创建完成,使用bean
11.spring容器关闭时调用disposableBean中的destory()方法
spring的作用域:默认的是单例,singleton,prototype,request,session,application
spring框架中的单例bean是线程安全的么
不是线程安全的,spring中的bean默认是单例模式,框架并没有对bean进行多线程的封装处理。
如果bean是无状态的,没有线程安全问题
如果bean是有状态的,则会出现线程安全文件,
有状态就是有数据保存(比如说共享变量),无状态就是没有数据保存
dao会操作数据库connection,connection是带有状态的,可用使用spring的事物管理器Threadlocal为不同线程维护一套独立的connection副本,保证线程间不受影响。
spring框架有那些设计模式
1.工厂模式 2.单例模式 3.适配器模式 4.装饰器模式 5.动态代理6.观察者模式7.策略模式
spring事物的实现方式和原理以及隔离级别
两种实现方式:一种是编程式(自己手动编程实现API的方法),一种是申明式 @transactional注解就是申明式事物
事物这个概念是数据库层次的,spring只是基于数据库中的事物进行了扩展,比如说加@transactional就开启了事物
原理:
在一个方法上加@transactional注解后,spring会基于这个类生成一个代理对象,将会代理对象作为bean,当使用这个代理对象方法时,如果这个方法存在@transactional注解,那么代理逻辑先把事物的自动提交设置为false,然后再去执行原本的业务逻辑方法,如果逻辑没有异常,那么就会将事物进行提交,如果业务逻辑出现异常,就会进行回滚。
spring的隔离级别就是数据库的隔离级别:外加一个默认级别
1.未提交读 2.提交读,不可重复读(orcal隔离级别) 3.可重复读 (mysql隔离级别)4.可串行化
如果spring自己手动配置了隔离,数据库配置的隔离级别,会被spring配置隔离级别覆盖,如果数据库不支持,最终取决于数据库
spring事物的传播机制
required(spring默认的传播类型):如果当前没有事物,则自己新建一个事物,如果前者存在事物,则加入事物
spring事物什么时候会失效?
spring的原理是aop,调用的是aop的代理对象,如果aop不起作用则会失效。
1.发生自调用,类使用了this调用本方法,此时this不是代理对象,而是userService本身。(解决方法,让this变为userService的代理类即可)
2.方法不是public @transactional只能用于public
3..数据库不支持事务
4.没有被spring管理
5.异常被吃了,catch掉,事务不会回滚。
springmvc的工作流程
1.用户发送请求至前段控制器dispatcheservlet
2. dispatcheservlet收到请求调用handlerMappeing处理器映射器。
3.处理器映射器找到具体的处理器(可以根据xml配置,注解进行查找),生成处理器及拦截器(如果有则生成)并返回给dispatcheservlet
4.dispatcheservlet调用handlerAdapter处理器适配器
5.handlerAdapter处理器适配器,经过适配调用具体的处理器(controller,后端控制器)
6.controller执行完返回modelandView
7.handlerAdapter处理器适配器将controller的执行结果modelandView返回dispatcheservlet
8.dispatcheservlet将modelandView传给viewResiover视图解析器
9.viewResiover视图解析器返回具体的view视图
10.dispatcheservlet根据view视图进行渲染
11.dispatcheservlet响应回用户
springmvc的9大组件?
1.HandlerMapping 处理器映射器
2.HandlerAdapter 适配器
3.viewResiover视图解析器 其他的没有了解
springboot的自动配置
springboot的一个组合注解也是核心注解springBootapplication
三个重要的注解:
1.springBootConfiguration 主配置注解和configuration的作用一样,程序启动时会去加载配置类
2.EnableAutoconfiguration 自动装配的核心注解
Autoconfigurationpackage自动配置包下@import,给容器导入一个组件
AutoconfigurationimportSelector的类里面有一个方法selectimports会返回一个字符串数组,放的是类的全路径,spring在读取全路径的时候会通过反射将这些类放到ioc容器中变成一个个兵,selectinports的字符串都是加载类路径下的mata-inf/spring.factories中的Autoconfiguration的key的value值,该文件保存着Autoconfiguration的key
自动配置的类由各个start提供,使用@Configuration+@bean定义配置类,放到mata-inf/spring.factories下使用spring spi扫描mata-inf/spring.factories的配置类,最后使用@inport导入配置类
2.componentSan 定义扫描包的路径
mybatis的优缺点
1.基于sql语句编程,相当灵活,不会对应用程序和数据库现有的设计造成任何影响,解除sql与代码的耦合
2.与jdbc相比,消除了jdbc的冗余代码,不需要手动关闭链接
3.能与spring很好的集成
4.很好的与各种数据库兼容
5.提供映射标签,支持对象与数据库的orm字段关系映射
缺点
对SQL语句依赖程度很高;并且属于半自动,数据库移植比较麻烦,比如mysql数据库编程Oracle数据库,部分的sql语句需要调整。
#{}和${}的区别
#{}是预编译,占位符,
${}是字符串替换,拼接符
mybatis在处理#{}时,会将sql中的#{}替换为?,调用preparedStatement来赋值 避免sql注入问题 提高系统安全性
mybatis在处理${}时,会将sql中的${}替换为变量值,调用Statement来赋值 有sql注入问题

浙公网安备 33010602011771号