常见问题
如何解决循环依赖的
先说网上流程很广的所谓的三级缓存吧 总之就是三个map。
假设A依赖B,B依赖A(非构造器互相依赖,构造器互相依赖无法解决) spring先创建a,然后把自己放到三级缓存中,然后进行依赖注入,发现依赖b,然后分别去一级、二级、三级缓存中找,都没找到 于是spring接着创建b,spring把b先new出来,然后把自己放入三级缓存中,然后进行依赖注入,发现依赖a,于是分别去一级、二级 三级缓存中找,结果在三级缓存中找到a,于是把a从三级缓存中移除并把a放到二级缓存中。然后b的依赖注入顺利完成,b创建成功,于是把自己从三级缓存中移除,放到一级缓存中。 然后回过了头接着对a进行依赖注入,然后再次从三个缓存中找,结果在一级缓存中找到了b,完成依赖注入,a创建完成,并把二级缓存中 移除,然后把自己放入一级缓存。
上面是网上广为流传的说法,这个说法我不是很赞同哈。
不赞同的点不是这个流程,这个流程应该和代码的相差不大,我不赞同的是我觉得这个说法夸大了所谓的缓存的作用,给人的感觉是因为三级缓存解决了循环依赖
实际不用三级,就用一个map也能搞定。因为只要能new出来,那么就能先能先让其他bean先引用
BeanFactory与FactoryBean的区别
看名字知道,BeanFactory是个bean工厂,也就是来生产bean的,由他生产的bean会经过spring的生命周期, 比如
populateBean
initilaizeBean
invokeAwareMethods
applyBeanPostProcessorsBeforeInitialization
invokeInitMethods
InitializingBean#afterPropertiesSet
自定义的init方法
applyBeanPostProcessorsAfterInitialization
然后FactoryBean是一个bean, 他既是一个普通的bean,也不是一个普通的bean.
说他是普通bean,是因为他和我们平常写的controller,service等一样,创建factorybean的时候也会经过上面的生命周期。
说他不是普通的bean,是因为这个bean又可以通过调用getObject方法来创建bean并交给spring管理。但是通过这个方法创建的bean就不会经过上面的生命周期。 可以通过这种方式来创建第三方jar包里的实例对象。 有点像我们平时用得@Bean注解一样(@Bean注解创建的bean也会经过spring的生命周期)
spring事务
按下面方式成对记忆
- REQUIRED, REQUIRED_NEW
- SUPPORTS, NOT_SUPPORTED
- MANDATORY, NEVER
- NESTED
SpringBootApplication注解
@SpringBootApplication可以看做下面三个注解的合集
@Configuration
允许在 Spring 上下文中注册额外的 bean 或导入其他配置类,用来标记当前类是一个配置类
@ComponentScan
扫描被@Component (@Repository,@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
@EnableAutoConfiguration
启用 SpringBoot 的自动配置机制
重点说说 @EnableAutoConfiguration
@EnableAutoConfiguration
这个注解上面有个import注解,import注解的使用看下文。 通过import注解导入了一个ImportSelector的实现类,类名想不起来了 我们知道如果导入的是一个ImportSelector的实现类,那么spring会执行里面的selectImports方法来得到需要创建 的bean的类全名。在这个实现类的这个方法里,会读取类路径下的spring.factories文件,这个文件就定义了各种普通类,配置类
总结:
如果我们自己写了组件,想要给被人使用,就可以在jar包中添加spring.factories文件,并把相关的配置类写上去,这样其他人只需要吧 这个jar包放入类路径下即可
通过spring.factories文件的方式是不需要其他额外工作就可以激活相关功能的,我们还可以也写一个类似Enable的注解, 再这个注解上面加上Configuration注解,或者import注解,这样只要在启动类上加上这个注解就能激活相关功能
@Import注解
可以导入几种类:
- 普通类
这个情况会创建这个普通的实例
- ImportSelector实现类
如果导入的是这个类,就会执行这个类的importSelect方法,这个方法会返回需要创建的bean的类全名, 然后spring就会根据类全名创建bean
- ImportBeanDefinitionRegistrar实现类
导入这种类型的类,就会执行这个类的registerBeanDefinitions方法, 可以在这个方法里定义BeanDefinition并进行注册,这样spring就能根据 BeanDefinition来创建bean
系统推荐
- 记一次内存泄漏
- Git合并多个提交并push到远程仓库
- 微博关注关系如何实现
- K8S 无感发布
- Spring RetryTemplate
- 搭建基于docker的elk平台来分析java日志
- 行转列不再复杂:SQL高手都在用的技巧揭秘
- Markdown软件比对
- 前后端常用技术
- RocketMQ
- ESRally性能测试步骤
- 批量替换文件名中的指定字符串
- 随机毒鸡汤:成绩不代表一切,成绩只是让别人,低头弯腰而已。