前言
心得体会
本系列是学习spring很唱一段时间之后的一系列学习笔记总结,包括spring篇,springmvc篇和springboot篇。
我们在项目的实际应用过程中,往往会觉得了解spring的原理没有什么用,不懂为什么,只需要会用,能用出来,发现诶,好像可以运行,结果可以出来就好了。但是往往在开发的过程中会发现,为什么这个启动类启动不了?为什么bean找不到,为什么maven依赖爆红,为什么bean注入不进来,我有启动类啊怎么还扫不到包,怎么往里添加配置类呀,meta下的factory为什么有这个,我们在添加配置类的时候为什么要写在spring.factories里,这些注解为什么加了就可以了,为什么加了注解还不好使,为什么redis启动类写进来了,我们明明只在nacos里配置了,它是怎么读取进去的呢,如何获取上下文?jsp里会出现为什么路径映射了却没有view数据等等问题。
上述的问题也是我在开发中遇到的一些问题,所以我觉得了解原理不仅仅是为了面试,更是为了我们开发中更流畅,更健壮的代码,更顺利的调试做铺垫,当然这种bug只有遇到了印象才会更加深刻,所以开发和原理往往结合进行的,缺一不可。
系列内容
本文是该系列的开端,我将会陆续写出springmvc系列和springboot系列,里面会有一些注解,原理之类的学习笔记和心得总结,希望能与大家共勉。
spring
spring部分主要是理解bean,可以把他理解成是做好的东西放到spring容器里,需要的时候可以随时去取
注解
一下省略@符号
spring部分的注解主要是围绕着bean的定义以及使用。
service,controller,component,respository等是用来实例化bean的
autowired是用来根据类型注入bean
qualifier集合autowired一起使用用来根据名称来进行依赖注入
scope标记bean的作用范围
configuration:标记当前是一个配置类,一般用于类级别
componentScan用来指定初始化容器扫描的包
bean:用来标记一个bean,作用一般在方法上,可以把方法返回值放到spring容器里
import:该注解导入的类会加载到ioc容器里面
aspect,标记切面类,after,before,around是用来切面变成
bean生命周期
通过BeanDefinition获取bean的定义信息->调用构造函数实例化bean-> bean的依赖注入-> 处理Aware接口(BeanNameAware、BeanFactoryAware、ApplicationContextAware) ->Bean的后置处理器BeanPostProcessor-前置-> 初始化方法(InitializingBean、init-method) ->Bean的后置处理器BeanPostProcessor-后置-> 销毁bean
创建bean和初始化赋值bean是分开的
aop
AOP称为面向切面编程,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。
以@Transactional注解为例,
可以定义一个切入点
@Pointcut(@annotation(这里就相当于是某个包下的Transactional类))
public void pointcut(){
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
//具体的方法:
//开启事务
//执行代码部分
//事务提交或者回滚事务
}
bean线程安全
spring里创建的bean默认是单例的,不过可以通过scope注解来定义是不是多例的。Scope("prototype")
bean循环依赖
循环依赖:循环依赖其实就是循环引用,也就是两个或两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于A 循环依赖在spring中是允许存在,spring框架依据三级缓存已经解决了大部分的循环依赖。
大部分循环依赖问题可以通过spring的三级缓存来解决。
构造方法出现循环依赖需要使用懒加载@Lazy