Skip to the content.

首页


IOC

IOC容器注解

FacotryBean、BeanFactory、ApplicationContext

@Scope

配合@Bean和@Component使用,指定bean的作用域。可以新增,使用ConfigurableBeanFactory的registerScope方法注册,或添加CustomScopeConfigurer,除了Singleton和Prototype之外都会生成Scope代理对象

Bean的生命周期

  1. Bean容器(通常是ApplicationContext)先创建所有的PostProcessor实例;
  2. 找到bean的定义,通过配置文件或扫描类文件;
  3. 使用反射创建Bean实例,如果是通过构造器注入,递归创建并注入属性;
  4. 如果实现了BeanNameAware等Aware接口则调用对应方法;
  5. 如果容器内存在BeanPostProcessor,则执行对应的postProcessBeforeInitialization()方法;
  6. 如果bean实现了InitializingBean,则执行afterPropertiesSet()方法;
    • SmartInitializingSingleton会在所有的单例模式Bean创建完成后执行,在InitializingBean之后。
  7. 执行Bean配置的init方法;
  8. 执行BeanPostProcessor的postProcessAfterInitialization()方法;
  9. 销毁Bean时,执行DestructionAwareBeanPostProcessor的postProcessBeforeDestruction()方法;
  10. 如果实现了DisposableBean接口,则执行destroy()方法;
  11. 执行Bean配置的destroy方法。

DI

注入方式

@Autowired

后置处理器为AutowiredAnnotationBeanPostProcessor,默认匹配方式byType,存在多个实现类时,则会使用byName方法,要指定具体的bean可以再添加一个@Qualifier注解或在实现类上添加@Primary注解,。

@Resource

属于jdk依赖注入注解,后置处理器为CommonAnnotationBeanPostProcessor,默认byName,其次byType,也可通过name和type属性具体指定。缺点是无法注解在方法参数上,且不支持配置required。

@Lazy

设置为延后加载,在依赖注入时为Bean生成代理类,首次被调用时才创建Bean,可用于解决构造器注入时的循环依赖问题

如何解决循环依赖

  1. Bean实例化完成后,会往三级缓存中加入当前‘半成品’Bean,实际上是添加一个ObjectFactory函数,其getObject方法实现为顺序使用所有SmartInstantiationAwareBeanPostProcessor类型的后置处理器的getEarlyBeanReference方法处理半成品Bean;
  2. 然后开始依赖注入,从各级缓存中查找,如果不存在则递归创建依赖的Bean;
  3. 存在循环依赖时,之后处理的Bean可以从三级缓存获取到ObjectFacotry,通过其getObject方法获取到之前处理的Bean的半成品注入;
  4. Bean依赖注入完成后,标记为完成并加入一级缓存中;
  5. 递归回退依次完成所有Bean的创建。

AOP

代理

Spring AOP默认使用Jdk动态代理,如果没有实现接口则使用cglib动态代理,只是使用了AspectJ的注解

动态代理

运行时增强,在程序运行期间创建代理类的字节码文件。

静态代理

编译时增强,效率高,代理类在编译阶段生成,程序运行前就已经存在。

@Pointcut

AOP下依赖循环问题如何处理

AOP的AbstractAutoProxyCreator为SmartInstantiationAwareBeanPostProcessor类型,其getEarlyBeanReference方法实现为使用半成品Bean创建代理对象并返回,同时还会将其加入二级缓存中;在其postProcessAfterInitialization方法中会为Bean创建代理对象,如果二级缓存中已经存在代理对象则直接获取。

若A、B互相依赖,A先创建,则B注入A时,注入的是通过getEarlyBeanReference方法创建的半成品A的代理对象;B依赖注入完成后在postProcessAfterInitialization方法中创建了B的代理对象,然后加入一级缓存内;递归回退到A的依赖注入后,A直接从一级缓存中获取到B的代理对象注入;A依赖注入完成后,执行postProcessAfterInitialization方法时,直接从二级缓存中获取到自己的代理对象,然后加入一级缓存中。


Spring MVC

DispatcherServlet

是属于Servlet容器的Bean。

流程

  1. 客户端请求会被提交到DispatcherServlet(前端控制器);
  2. DispatcherServlet请求一个或多个HandlerMapping(处理器映射器),并返回一个执行链(HandlerExecutionChain);
  3. DispatcherServlet将执行链返回的Handler信息发送给 HandlerAdapter(处理器适配器);
  4. HandlerAdapter根据Handler信息找到并执行相应的Handler(即Controller);
  5. Handler执行完毕后返回给HandlerAdapter一个ModelAndView对象,HandlerAdapter再将其返回给DispatcherServlet;
  6. DispatcherServlet接收到ModelAndView对象后,请求 ViewResolver(视图解析器)对进行解析;
  7. ViewResolver根据View信息匹配到相应的视图结果,并返回给 DispatcherServlet;
  8. DispatcherServlet将Model交给接收到的View进行渲染,然后返回给客户端。

Spring事务

编程式事务

声明式事务

基于AOP实现,故需要被spring管理、只能拦截public方法、内部调用无法生效。


Spring Data Jpa

通过JdkDynamicAopProxy创建代理对象,默认通过Hibernate执行数据库操作。


SpringBoot

@SpringBootApplication

@SpringBootConfiguration表示当前类为配置类;@EnableAutoConfiguration开启自动配置,通过【@Import(AutoConfigurationImportSelector.class)】实现;@ComponentScan开启包扫描,默认路劲为当前类所在的包。

AutoConfigurationImportSelector

即Spring的SPI机制,使用SpringFactoriesLoader扫描META-INF/spring.factories下配置的所有拓展点,并加载到IOC容器。

启动流程

通过SpringApplication.run()方法启动,步骤为:

  1. 启动监听器;
  2. 环境构建;
  3. 创建容器;
  4. 前置处理;
  5. 刷新容器(启动Spring IOC容器)
  6. 后置处理;
  7. 发出事件;
  8. 执行Runner。

使用的设计模式