Spring
Bean
bean 的生命周期
创建前准备。Bean 在开始加载之前,会去上下文配置中查找并解析 Bean 相关的扩张,比如:
初始化的方法 init-method 和 destroy-method
以及 BeanFactoryPostProcessor 这一类 Bean 加载过程中前置后置的处理创建实例。通过反射创建出 Bean 的实例对象,并且会扫描和解析 Bean 声明的属性。
但是此时的 Bean 是 Spring 内部的 Bean,不对外使用依赖注入。检查 Bean 是否依赖于其他的 Bean,如果存在则需要的这些 Bean 进行依赖注入
常见的注解有:@Autowired、@Qualifier、@Resource
特别注意:@Resource的注解是属于J2EE的,按照名称进行装配
与此同时会去执行 BeanPostProcessors 接口实例的 postProcessBeforeInitialization()方法初始化。组装成能够被使用的 Bean 对象。
如果Bean在XML文件中配置了init-method的方法、
实现了InitializingBean接口或者加上了@PostConstruct,会在这个阶段被调用
初始化结束后会去执行实现了
BeanPostProcessors接口的实例的postProcessAfterInitialization()方法容器缓存。将 Bean 保存到对应的容器以及 Spring 的缓存中,这个阶段结束,
Bean就可以被开发者使用了销毁实例。当应用上下文,也就是容器被关闭时,其中所有的 Bean 都会被销毁
如果Bean在XML文件中配置了destroy-method的方法、
实现了DisposableBean接口或者加上了@PreDestroy,会在这个阶段被调用
如何解决循环依赖
例如有两个 Bean A 和 B,A 依赖于 B,B 也依赖 A
初始化 bean 的时候会去一级缓存中查找,没有则去二级,
再没有则会通过存放 ObjectFactory 的三级缓存中得到一个半成品 bean,并放到二级缓存
而第一次加载 A,一级缓存和二级缓存肯定都是没有的,
所以会去三级缓存中拿到一个半成品 A,并放到二级缓存
此时 A 需要注入 B,同样的,第一次加载 B 肯定一二级缓存都没有,所以也会去三级缓存中
拿到一个半成品 B,并放到二级缓存
当 B 发现也需要注入 A 时,它此时就会在二级缓存中找到 A
这个时候将 A 注入到 B 中,同时删除二级缓存中的 B,添加到一级缓存中
当 B 注入完成后,A 又把一级缓存中的 B 注入到自己中来,并且删除二级缓存中的 A,添加到一级缓存
IOC
实现自动注入的方式
- @Autowired 一个实现类匹配
- @Qualified 多个实现类指定
- @Resource J2EE的,指定一个类
AOP
Spring AOP 原理
AOP,Aspect Oriented Programming,面向切面编程
AOP分静态AOP和动态AOP。
静态 AOP 是指 AspectJ 实现的 AOP,将切面代码直接编译到 Java 类文件中
动态 AOP 是指将切面代码进行动态织入实现的 AOP
Spring AOP使用的是动态 AOP,
主要采用了 JDK 提供的动态代理技术和 CGLIB 中的动态字节码增强技术
动态代理技术:
实现原理是通过 target 和代理类实现同一个接口,代理类持有 target 对象,
来达到方法拦截的作用。
弊端:- 必须保证 target 类实现接口
- 如果想要对 target 方法进行拦截,那么这些方法都要在接口中声明,略微限制
动态字节码增强技术:
它既可以代理实现类,也可以代理接口。
底层是使用了 ASM (一个通用的 Java 字节码操作和分析框架)从而动态地生成被代理的子类
而它的原理是通过对字节码进行 CURD 操作,从而在 target 类的基础上生成 target 子类进而达到对方法的拦截
MVC
Spring MVC 执行流程

Boot
Spring Boot 启动机制
- @SpringBootConfiguration
它将启动类作为一个配置类加载到 Spring 容器中 - @EnableAutoConfiguration = @AutoConfigurationPackage + @Import
注册 spring 内部的 bean 以及插件式 bean,
例如 Nacos 里面的一些类就是在这一步通过 SPI注入进来 - @ComponentScan
扫描程序员在启动类目录下的 bean
Spring Boot 有哪些优点
- 配置变得简单,支持yml、properties进行配置
- 快速整合第三方框架
- 内嵌了servlet容器,比如Tomcat
- 注解化配置,避免了编写大量的样板代码,注释和XML配置
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!