spring框架面试


框架篇

1.refresh 流程

refresh 是 AbstractApplicationContext 类下的一个方法,用来初始化applicationContext,容器必须调用refresh才能正常调用。它的内部主要调用12个方法,我们称它为refresh的12个步骤。这12个方法按功能分类:为环境准备,准备beanFactory,准备applicationContext,初始化 BeanFactory 中的非延迟单例bean。

准备环境:prepareRefresh

准备beanFactory:obtainBeanFactory,prepareBeanFactory,postProcessBeanFactory,invokeBeanFactoryPostProcessors,

RegisterBeanPostProcessors

准备 ApplicationContext:

initMessageSource,initApplicationEventMuticaster,onrefresh,registerListenners,finishRefresh

初始化 BeanFactory 中的非延迟单例bean:

finishRefresh

2.spring bean 生命周期

bean 的生命周期从 beanFactory 的 getBean 到 bean 的销毁,有七个步骤:

1.处理名称 2.检查缓存 3.处理depends on 4.选择scope策略 5.创建bean 6.类型转化处理 7.销毁bean

3.spring bean 的循环依赖

循环依赖的产生,bean的创建没有按照步骤。bean创建的步骤一定是,创建,注入,初始化

set的循环依赖解决(so easy)

构造方法的循环依赖的解决

思路一:

? a注入b的代理对象,保证a能跑通

? 后续用到b的真实对象,通过代理间接跑通

思路二:

? a注入b的工厂对象,让b的实例创建被推迟,保证a的流程可以先跑通

? 后续用到b的真实对象时,在通过工厂间接访问

写一下动态代理

// Jdk 动态代理 必须有接口
(A)Proxy.newProxyInstance(T.class.getClassLoader(),new Class[]{A.class},new XHandler(T t));
public class XHandler implements InvocationHandler {
    T t;
    public XHandler(T t){
        this.t = t;
    }
    @Override
    public Object invoke(Object proxy,Method method,Object[] args) throws Throwable {
        // 方法前增强
        Object o = method.invoke(t,args);
        // 方法后增强
        return o;
    }
} 

// cglib 动态代理(生成的代理对象是子类)被代理的类不能是final
Enhancer enhancer = new Enhancer();
enhancer.setSuperClass(Tank.class);
enhancer.setCallback(new TimeMethodInterceptor());
Tank tank = (Tank)enhancer.create();
tank.move();

class TimeMethodIntercepter implements MethodInterceptor{
    @Override
    public Object intercept(Object o,Method method,Object[] args,MethodProxy methodProxy) {
        // 方法前增强
        Object result = methodProxy.invokeSuper(o,args);
        // 方法后增强
        return result;
    }
}

解决set循环依赖

一级缓存:

? 限制bean在beanFactory中只保存一份,即实现 Singleton scope

作用:

? 第一次走getBean("a")流程后,最后会将成品a放入 SingletonObjects 一级缓存

? 后续走getBean("a"),直接从缓存里面拿成品对象

一级缓存无法解决set的循环依赖:

? A需要B,B需要A,没有一个先走完,陷入死循环

二级缓存(spring中称之为三级缓存):

? 在增加一个SingletonFactories缓存

? 在依赖注入前,即 a.setB() 以及 b.setA() 将 a 及 b 的半成品对象(未完成依赖注入和初始化)放入SingletonFactories里

? 执行依赖注入时,拿缓存中的半成品对象,走完流程即可

? 无法正确处理循环依赖并且包含有代理创建的场景

三级缓存

? 使用三个缓存区解决

4.spring 事务失效

八种场景

1.抛出检查异常导致事务不能正确回滚

2.业务方法内自己 try catch 异常导致事务不能回滚

3.aop切面顺序导致事务不能正确回滚

4.非public方法导致事务失效

5.父子容器导致事务失效

6.调用本类方法导致传播行为失效

7.@Transactional 没有保证原子行为

8.@Transactional 方法导致的 synchronized 失效

5.spring MVC执行流程

首先得知道四个核心类

DispatcherServlet,

HandleMapping,

HandleAddapter,

viewResolver

6.spring 注解

lang、事务、监控、核心、(事件、调度、异步)、切面、组件扫描与配置类、缓存、依赖注入

web(mapping、rest、统一处理、参数、转换与格式化、validation、scope、ajax)

boot(auto、condition、properties、convert、其它)

7.spring boot 自动注解原理

@SpringBootConfiguration 是一个组合注解,由@ComponentScan 、@EnableAutoConfiguration和@SpringBootConfiguration 组成

1.@SpringBootConfiguration 与 普通的 @Configuration相比,唯一区别就是要求整个app中只出现一次

2.@ComponentScan

? excludeFilters -用来组件扫描时进行排除,也会排除自动类

3.@EnableAutoConfiguration 也是一个组合注解 - 用来标记扫描的包

? @AutoConfigurationPackage- 用来记住扫描的起始包

? @Import(AutoConfigurationImportSelector.class) 用来加载 MATA-INFO/spring.factories 中的自动配置类

8.spring 中的设计模式

Singleton

builder

Factory Method

Adapter

Composite

Decorator

proxy

chain of responsibility

Observer

Strategy

Template Method