常见问题

Rocky大约 6 分钟

如何解决循环依赖的

先说网上流程很广的所谓的三级缓存吧 总之就是三个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事务

按下面方式成对记忆

  1. REQUIRED, REQUIRED_NEW
  2. SUPPORTS, NOT_SUPPORTED
  3. MANDATORY, NEVER
  4. NESTED

SpringBootApplication注解

@SpringBootApplication可以看做下面三个注解的合集

  1. @Configuration

    允许在 Spring 上下文中注册额外的 bean 或导入其他配置类,用来标记当前类是一个配置类

  2. @ComponentScan

    扫描被@Component (@Repository,@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。

  3. @EnableAutoConfiguration

    启用 SpringBoot 的自动配置机制

重点说说 @EnableAutoConfiguration

@EnableAutoConfiguration

这个注解上面有个import注解,import注解的使用看下文。 通过import注解导入了一个ImportSelector的实现类,类名想不起来了 我们知道如果导入的是一个ImportSelector的实现类,那么spring会执行里面的selectImports方法来得到需要创建 的bean的类全名。在这个实现类的这个方法里,会读取类路径下的spring.factories文件,这个文件就定义了各种普通类,配置类

总结:

  1. 如果我们自己写了组件,想要给被人使用,就可以在jar包中添加spring.factories文件,并把相关的配置类写上去,这样其他人只需要吧 这个jar包放入类路径下即可

  2. 通过spring.factories文件的方式是不需要其他额外工作就可以激活相关功能的,我们还可以也写一个类似Enable的注解, 再这个注解上面加上Configuration注解,或者import注解,这样只要在启动类上加上这个注解就能激活相关功能

@Import注解

可以导入几种类:

  1. 普通类

    这个情况会创建这个普通的实例

  2. ImportSelector实现类

    如果导入的是这个类,就会执行这个类的importSelect方法,这个方法会返回需要创建的bean的类全名, 然后spring就会根据类全名创建bean

  3. ImportBeanDefinitionRegistrar实现类

    导入这种类型的类,就会执行这个类的registerBeanDefinitions方法, 可以在这个方法里定义BeanDefinition并进行注册,这样spring就能根据 BeanDefinition来创建bean


系统推荐









  • 随机毒鸡汤:上班如上坟,别侮辱坟,上坟还有思念和敬畏之情呢。