Spring 面试题(总结)

一.AOP

你所知道的AOP

先谈谈OOP(面向对象编程),把实际业务中的所用到的实体属性和动作封装起来,进行更搞笑的逻辑单元划分.AOP是针对业务处理过程的切面进行提取,以获得逻辑过程中的各部分之间的低耦合隔离效果

为什么用AOP

1.为了方便,重复代码的编写交给框架来完成
2.为了更清晰的逻辑,可以让你的业务逻辑去关注自己本身的业务,而不去想一些其他的事情,这些事情包括:安全、事务、日志等

AOP术语

1.通知(Advice)

就是你想要的功能,也就是上面说的安全,事务,日志等.自己先定义好,然后在想用的地方用一下

2.连接点(JoinPoint)

Spring允许你使用通知的地方,基本每个方法前后,或抛出异常时都可以是连接点,Spring只支持方法连接点,其他如apectj还可以让你在构造器或属性注入时都行,不过那不是咱关注的,只要记住,和方法有关的前前后后(抛出异常),都是连接点.

3.切入点(Pointcut)

上面说的连接点的基础上,来定义切入点,你的一个类里,有15个方法,那就有几十个连接点了对吧,但是你并不想在所有方法附近都使用通知(使用叫织入),你只想让其中的几个,在调用这几个方法之前,之后或抛出异常时干点什么.那么久用切点来定义这几个方法,让切点来筛选连接点,选中那几个你想要的方法.

4.切面(Aspect)

切面是通知和切入点的结合.现在发现了吧,没切入点什么事情,连接点就是为了让你更好理解切点,搞出来的,明白这个概念就行了.通知说明了干什么和什么时候干(什么时候通过方法中的 before ,after,around等就能知道),而切入点说明了在哪干(指定在哪个方法上), 那就是一个完整切面的定义

5.引入(introduction)

允许我们向现有的类添加新方法属性.这不就是把切面(也就是新方法属性:通知定义的)用到目标类中吗

6.目标(target)

引入中提到的目标类,也就是要被通知的对象,也就是真正的业务逻辑,他可以在毫不知情的情况下,被咱织入切面.而自己专注于业务本身的逻辑.

7.代理(proxy)

怎么实现整套aop机制的,都是通过代理,这个一会细说.

8.织入(weaving)

把切面应用到目标对象来创建新的代理对象的过程.有3种方式,Spring
关键就是:切点定义了哪些连接点会得到通知

AOP原理

Spring用代理类包裹切面,把他们织入到Spring管理的bean中.也就是代理类伪装成目标类,它会截取对目标类中方法的调用,让调用者对目标类的调用都先变成调用伪装类,伪装类中就先执行了切面,再把调用转发给真正的目标bean.
现在可以自己想想,怎么搞出来个伪装类,才不会被调用者发现(过JVM的检查,JAVA是强类型检查,哪里都要检查)
1.实现和目标类相同的接口,我也实现和你一样的接口,反正上层都是接口级别的调用,这样我就伪装成了和目标类一样的类(实现了统一接口,咱是兄弟了),也就逃过了类型检查,到java运行期的时候,利用多态的后期绑定(所以Spring采用运行时),伪装类(代理类)可变成了接口的真正实现,而他里面包裹了真实的那个目标类,最后实现具体功能的还是目标类,只不过代理类之前干了点事情(写日志,安全检查,事务等)

这就好比,一个人让你办件事,每次这个时候,你弟弟就会先出来,当然他分布出来,以为是你,你这个弟弟虽然办不了这件事但是知道你能办,所以就答应下来了,并且收了点礼物(写日志),收完礼物了,把事给人家办了,所以你弟弟又找你这个哥哥来了,最后把这事办了的还是你自己.但是你自己并不知道你弟弟已经收礼物了,你只是专心把这件事做好.

顺着这个思路想,要是本身这个类就没实现一个接口呢,你怎么伪装我,我就压根没有机会让你搞出来这个双胞胎弟弟,那么久用第二种代理方式,创建一个目标类的子类,生个儿子,让儿子伪装我.

2.生成子类调用,这次用子类来做伪装类,当然这样也能逃过JVM的强类型检查,我继承的吗,当然查不出来,子类重写了目标类的所有方法,当然在重写的方法中,还在这些功能之前,实现了一些其他的(写日志、安全检查、事务等)

这次的对比就是,儿子先从爸爸那把本事都学会了,所有人都找儿子办事,但是儿子每次办和爸爸同样的事之前,都要收点小礼物(写日志),然后才去办真正的事.当然爸爸是不知道儿子这么干的了.这里有件事情要说,某些本事是爸爸独有的(final定义的),儿子学不了,学不了就办不了这件事,自然就不能收人家礼了

前一种兄弟模式,Spring会使用JDK的 Proxy类,它允许Spring动态生成一个心累来实现必要的接口,织入通知,并且把这些类的任何调用都转发到目标类

后一种父子模式,Spring使用CGLIB库生成目标类的一个子类,在创建这个子类的时候,Spring织入通知,并且把这个子类的调用委托到目标类

相比之下,还是兄弟模式好些,他能更好的实现松耦合,尤其在今天都高喊着面向接口编程的情况下,父子模式只是在没有实现接口的时候,也能织入通知,应当做一种例外

二.事务

事务传播行为种类

Spring在TransactionDefinition接口中规定了7中类型的事务传播行为,它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播
事务传播行为类型

事务传播行为类型说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务,加入到这个事务中.这是最常见的选择
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,则以非事务的方式执行
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式执行此操作,如果当前存在事务,就把当前事务挂起
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行.如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作

BeanFactory

BeanFavctory与ApplicationContext的区别

1.BeanFactory采用的是延迟加载形式来注入bean的,即只有在使用到某个bean的时候(调用getBean()),材对该bean进行加载实例化,这样,我们就不能发现一些存在的Spring配置问题.而ApplicationContext则相反,它是在容器启动的时候,一次性创建了所有的bean.这样,在容器启动的时候,我们就可以发现Spring中存在的配置错误

2.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值