spring的面试题

1.bean的生命周期

1)实例化(CreateBeanInstance)

在Java堆内存开辟空间,通过反射的方式生成对象

2)设置属性

  1. 用户自定义属性赋值/注入依赖,如果出现循环依赖,需要解决循环依赖(populateBean())
  2. 容器对象赋值/调用Aware接口(invokeAwareMethods),完成BeanName,BeanFactroy,BeanClassLoader对象的属性设置

3)初始化 (Initialization)

  1. 调用BeanPostProccessor的前置接口 postProcessBeforeInitialization() (ApplicationContextPostProcessor、ApplicationContext、Environment、ResourceLoader等对象)
  2. InvokeInitMethod(),判断当前bean对象是否设置了InitializingBean接口,然后进行属性的设置等基本工作
  3. 如果当前bean对象定义了初始化方法(afterPropertiesSet),那么在此处调用初始化方法
  4. 调用BeanPostProccessor的后置接口-postProcessAfterInitialization(), Spring中的Aop就是在这实现的(AbstractAutoProxyCreator)

4)调用对象(getBean)

5)销毁(Destruction)

  1. DisposableBean的destory()方法
  2. 自定义的destoryMethod指定方法

2.spring的事务传播机制

解析:

这是spring自带的,而非数据库的。

多个事务方法互相调用时,事务如何在这些方法之间进行传播,spring中提供了7种不同的传播特性,来保证事务的正常运行:

REQUIRED:默认的传播特性,如果当前没有事务,则新建一个事务,如果当前存在事务,则加入这个事务。

SUPPORTS:当前存在事务,则加入当前事务,如果当前没有事务,则以非事务的方式执行。

MANDATORY:当前存在事务,则加入当前事务,如果当前不存在事务,则抛出异常。

REQUIRED_NEW:创建一个新事务,如果当前存在事务,则把当前事务挂起。

NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则把当前事务挂起。

NEVER:以非事务方式进行,如果当前存在事务,则抛出异常。

NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作。

REQUIRED_NEW与NESTED的区别:

REQUIRED_NEW是新建一个事务并且新开始的这个事务与原有事务无关;而NESTED则是当前存在事务是会开启一个嵌套事务。在NESTED情况下,父事务回滚时,子事务也会回滚,而REQUIRED_NEW情况下,原有事务回滚,不会影响新开启的事务。

NESTED和REQUIRED的区别:

REQUIRED情况下,调用方存在事务时,则被调用方和调用方使用同一个事务,那么当被调用方出现异常时,由于共用一个事务,所以无论是否catch异常,事务都会回滚;而在NESTED情况下,被调用方发生异常时,调用方可以catch异常,这样只有子事务回滚,父事务不会回滚。

3.Spring中Bean的作用域有哪些?

Spring 4.3 中为Bean定义了7种作用域

  • singleton:使用singleton定义的Bean 在Spring容器中将只有一个实例,也就是说,无论有多少个Bean引用它,始终将指向同一个对象。这也是Spring容器默认的作用域。
  • prototype:每次通过Spring容器获取的prototype定义的Bean时,容器都将创建一个新的Bean实例。
  • request:在一次HTTP请求中,容器会返回该Bean的同一实例。对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Request内有效。
  • session:在一次HTTP session中,容器会返回该Bean的同一实例。对不同的HTTP请求则会产生一个新的Bean,而且该Bean仅在当前HTTP Session内有效。
  • globalSession:在一个全局的HTTP Session 中,容器会返回该Bean的同一实例。仅在使用portlet上下文时有效。
  • application:为每个ServletContent对象创建一个实例。仅在Web相关的ApplicationContext中生效。
  • websocket:为每个websocket对象创建一个实例。仅在Web相关的ApplicationContext中生效。

4.Spring的核心

Spring的核心:IOC控制反转、AOP面向切面的编程

IOC和DI

  • IOC容器和DI依赖注入
  • 本质上IOC和DI是同一思想下不同维度的表现,IOC是bean的注册,DI是bean的初始化

IOC容器( Inverser Of Control反转控制):就是把原来在程序中创建HelloService对象的控制权限交给Spring管理,即HelloService对象控制器被反转到Spring框架内

// 方式1:普通创建对象方式
HelloServiceImpl helloServiceImpl = new HelloServiceImpl();
helloServiceImpl.setInfo("测试");
helloServiceImpl.sayHello();
​
// 方式2:IOC
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/applicationContext.xml"); 
HelloService service = (HelloService)ac.getBean("helloService");
service.sqyHello();

DI: 依赖注入 在Spring框架负责创建Bean对象的时候 动态的将数据注入到Bean的组件

<bean id="helloService" class="com.sz.test.HelloServiceImpl">
  <property name="info" value="测试"></property>
</bean>

IOC容器装配Bean的方式就是实例化该对象的方式,Spring提供了三种装配Bean的方式

使用类的构造函数进行初始化 (默认是无参的构造函数)
使用静态工厂方法:利用factory-method=属性指定静态工厂方法
使用实例化工厂方法 (工厂模式)

AOP

  • aop概念

AOP(Aspect Oriented Programing)面向切面编程:其底层实现原理是“代理机制”

AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码

AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入

应用分析

日志模块:传统方式实现DAO操作的日志记录,需要在相应方法中调用相关的日志操作方法

class UserDAO{
  // 日志记录操作
  public void writeLog(){
    // 执行日志记录操作
   ......
 }
  
  // 业务操作
  public void update(){
    // 调用日志记录操作
    writeLog();
    // 业务操作
   ......
 }
}

纵向继承:随着业务的迭代,不同业务相应需要记录日志(通过定义BaseDAO抽离公共日志操作概念)

abstract class BaseDAO{
  // 日志记录操作
  public void writeLog(){
    // 执行日志记录操作
   ......
 }
}
​
// 子业务1
public subBusinessDAO1 extends BaseDAO{
  // 直接在业务方法中调用父类BaseDAO的日志操作
}
​
​
// 子业务2
public subBusinessDAO2 extends BaseDAO{
  // 直接在业务方法中调用父类BaseDAO的日志操作
}

代理机制:采用AOP横向抽取机制完成代码的复用

客户端->通过监听子业务DAO的指定方法,访问自定义代理类OperLogProxy
自定义OperLogProxy,将需要复用的代码放入该代理类中(例如此处的writeLog方法)

AOP应用场景

aop框架种类包括:aspectJ、JBoss AOP、Spring AOP

性能监控:在方法调用前后记录调用时间,方法执行太长或超时报警

缓存代理:缓存某方法的返回值,下次执行该方法时,直接从缓存里获取

软件破解:使用AOP修改软件的验证类的判断逻辑

记录日志:在方法执行前后记录系统日志

工作流系统:工作流系统需要将业务代码和流程引擎代码混合在一起执行,可用AOP将其分离,并动态挂接业务

权限验证:方法执行前验证是否有权限执行当前方法,没有则抛出没有权限执行异常,由业务代码捕捉

AOP的五类Advice

AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Advice

Spring按照通知Advice在目标类方法的连接点位置,可以分为5类

前置通知 org.springframework.aop.MethodBeforeAdvice

在目标方法执行前实施增强

后置通知 org.springframework.aop.AfterReturningAdvice

在目标方法执行后实施增强

环绕通知 org.aopalliance.intercept.MethodInterceptor

在目标方法执行前后实施增强

异常抛出通知 org.springframework.aop.ThrowsAdvice

在方法抛出异常后实施增强

引介通知 org.springframework.aop.IntroductionInterceptor

在目标类中添加一些新的方法和属性

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值