spring 常见面试题

1. 控制反转IOC

1.1 什么是Spring IOC 容器?

控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的权限交给容器,通过容器来实现对象组件的装配和管理。

Spring IOC 负责创建对象,管理对象(通过依赖注(DI),装配对象,配置对象,并且管理这些对象的整个命周期。

1.2 控制反转(IoC)有什么作?

  • 管理对象的创建和依赖关系的维护。对象的创建并不是⼀件简单的事,在对象关系⽐较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的

  • 解耦,由容器去维护具体的对象

  • 托管了类的产过程,如我们需要在类的产过程中做些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的。

1.3 IOC 的优点是什么?

  • IOC 或 依赖注把应用的代码量降到最低。

  • 它使应用容易测试,单元测试不再需要单例和JNDI查找机制。

  • 最小的代价和最小的侵性使松散耦合得以实现。

  • IOC容器支持加载服务时的饿汉式初始化和懒加载。

1.4 Spring IoC 的实现机制

Spring 中的 IoC 的实现原理就是工厂模式加反射机制。

2. 什么是 Spring 的依赖注?

依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。注入方式有:构造器、属性、setter方法。

3. Spring 框架中的单例 bean 是线程安全的吗?

不是,Spring框架中的单例 bean 不是线程安全的。

spring 中的 bean 默认是单例模式,spring 框架并没有对单例 bean 进行多线程的封装处理。

spring 通过 ThreadLocal 对一些 bean 进行了非线程安全处理,解决线程安全问题。例如:HttpServletRequest,所以在 Controller 中注入 HttpServletRequest是线程安全的。

ThreadLocal 会为每个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每个线程都拥有自己的变量副本,从也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。

4. Spring 框架中 bean 的生命周期?

spring 生命周期中的阶段,包括:初始化、使用、销毁。

  1. 初始化阶段
    1. 调用bean的构造函数,创建实例;
    2. 进行参数依赖注入;
    3. 若实现org.springframework.beans.BeanNameAware接口,则调用BeanNameAware的setBeanName()方法;
    4. 若实现org.springframework.beans.factory.BeanClassLoaderAware接口,则调用BeanClassLoaderAware的setBeanClassLoader()方法;
    5. 若实现org.springframework.context.ApplicationContextAware接口,则调用ApplicationContextAware的setApplicationContext()方法;
    6. 若使用了注解@PostConstruct,则调相应方法;
    7. 若实现org.springframework.beans.factory.InitializingBean接口,则调用InitializingBean接口的afterPropertiesSet方法;
    8. 若bean定义的使用了initMethod,则调相应方法;
    9. 若实现org.springframework.beans.factory.config.BeanPostProcessor接口,则调用BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitialization方法;
  2. 使用阶段
    bean在项目的使用;
  3. 销毁阶段
    1. 若使用注解@PreDestroy,则调用相应方法;
    2. 若bean定义中配置了destroyMethod,则调用相应方法;
    3. 若实现org.springframework.beans.factory.DisposableBean接口,则调用DisposableBean接口的destroy方法;

5 Spring 中 @Autowired 和 @Resource 之间的区别?

@Autowired 和 @Resource 之间的区别?

  1. 注解内部定义的参数不同:

    @Autowired 内部只有一个参数 required,默认值为 true

    @Resource 内部有多个参数,比较重要的有 nametype

  2. 默认注入方式不同:

    @Autowired 默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。

    @Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的 bean 才会按照类型来装配注入。

  3. 注解应用范围不同:

    @Autowired 可用用在构造方法、方法、方法参数、成员变量、注解上。

    @Resource 可用用在 类、方法、成员变量

  4. 出处不同:

    @Autowired 是 spring 定义的注解。

    @Resource 是由 jdk 提供的,它遵循 JSR-250 这个规范。

    所以 @Autowired 只适用于 spring 框架,而 @Resource 适用于所有的 Java 框架 。

6. JDK 动态代理和 CGLIB 动态代理的区别

Spring AOP中的动态代理主要有两种式,JDK 动态代理和 CGLIB 动态代理:

JDK动态代理只提供接口的代理,不支持类的代理。核心 InvocationHandler接口和Proxy类,InvocationHandler通过invoke()方法反射来调用目标标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。

如果代理类没有实现 InvocationHandler接口,那么 Spring AOP 会选择使 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成成指定类的一个类的子对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法法使用 CGLIB做动态代理的。运行是生产代理类。

7. BeanFactory 和 FactoryBean 的区别 ?

BeanFactory 保存了所有需要对外提供的 Bean 的实例。相当于 IoC 容器的顶级接口,是 IoC 容器最基础的实现。提供访问 spring 容器的根接口。主要负责 bean 的创建和访问。其中最主要的一个方法是 getBean() 方法。完成对 Bean 的依赖注入的功能。

FactoryBean 是一个特殊的 Bean,它可以返回创建 bean 的工厂,如果配置不同的类,可以返回不同类型的 bean,它有一个比较核心的方法叫做 getObject()。可以在 beanName 前面加上 & 符号获取 bean 对应的 Factory。同时可以通过自定义 FactoryBean来扩展创建 Bean的规则。

8. 单例模式

破坏单例模式的方法:

  1. 反射:

    处理方法:添加一个标记,在构造方法里面判断改标记

  2. 序列化

    处理方法:重写readResolve

  3. 实现Cloneable接口的clone

    处理方法:不要实现Cloneable接口的clone方法

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值