ioc

ioc

总结:

1、加载配置文件两种方式

①xml配置读取ClassPathXmlApplicationContext②注解扫描AnnotationConfigApplicationContext

 

2、注解@Bean(注册bean)、@ComponentScan(指定要扫描的包)、@Scope(默认单例singleton、prototype多例)、@Lazy(懒加载,在调用的时候创建对象)

@Conditional(满足条件才注册bean,传入一个数组,里面是类信息,这个类要求实现Condition接口,返回true或false)、

@Import(给容器中导入组件)、ImportSelector(接口,实现返回一个类全名的字符串数组,就会注册到容器)、ImportBeanDefinitionRegistrar(接口,BeanDefinitionRegistrar的api进行手工注册)、FactoryBean(接口)

/**
* 给容器中注册组件
* 1)包扫描+组件注解(@Controller/@Service/@Repository/@Component)
*2)@Bean【导入第三方包里的组件】
* 3)@Import【快速给容器中导入一个组件】,
*    ①@Import({}),ioc容器就会自动注册这个组件,默认id是全类名
*    ImportSelector接口,返回一个全类名的数组
*    registerBeanDefinitions接口,手工注册bean
*  4)使用spring的FactoryBean
*      ①默认获取到的是工厂bean调用getObject创建的对象
*      ②要获取bean本身,我们给id加一个&,就可以获取工厂bean本身
*
*/

 

 

3、bean的生命周期:创建(单例创建时创建对象、多例获取时创建)->初始化(对象创建好,并赋值好)->销毁(单例容器关闭时销毁,多实例不会销毁)

4、@PostConstruct(在bean创建完成并赋值完成后执行)、@PreDestroy(在容器销毁bean之前通知我们进行清理工作)

5、BeanPostProcessor(接口,后置处理器,bean的赋值,注入组件,@Autowired,生命周期注解都是实现了这个接口。AutowiredAnnotationBeanPostProcessor)

6、@Value:三种赋值方法①字符串②spring表达式#{}③取出配置文件的值(在运行环境变量中的值)${},@PropertySource(value={"classpath:/xxx.properties"})读取配置文件

7、@Autowired(自动注入,默认是变量名称作为id去容器中找寻bean)、@Qulifier(指定属性名称去容器key找寻bean)、@Primary(在没有指定装配的情况下,默认装配)

8、@Resource(jdk的注入bean的方式,使用属性名称去容器中找bean,但是不能配合@Qulifier、@Primary)、@Inject(需要导入inject依赖,可以配合spring的两个注解,但是没有required=false属性)

9、其他注入方式:构造器注入(如果只有一个构造器、@Autowired可以省略)

10、@Profile:根据不同的系统属性,动态的激活和切换一些组件。

 

spring如何解决循环依赖

Spring中单例Bean的三级缓存

第一级缓存〈也叫单例池)singletonObjects:存放已经经历了完整生命周期的Bean对象

第二级缓存: earlySingletonObjects,存放早期暴露出来的Bean对象,Bean的生命周期未结束(属性还未填充完整)

第三级缓存: Map<String, ObiectFactory<?>> singletonFactories,存放可以生成Bean的工厂

 

一级缓存:用于存储被完整创建了的bean。也就是完成了初始化之后,可以直接被其他对象使用的bean。

二级缓存:用于存储半成品的Bean。也就是刚实例化但是还没有进行初始化的Bean

三级缓存:半成品的代理Bean对象。工厂对象可以产生Bean对象提前暴露的引用,执行这个lambda表达式,就会将引用放入二级缓存中

 

getSingleton:希望从容器里面获得单例的bean,没有的话doCreateBean: 没有就创建beanpopulateBean: 创建完了以后,要填充属性addSingleton: 填充完了以后,再添加到容器进行使用

 

A依赖B,B依赖A

 

1、A创建过程中需要B,于是先将A放到三级缓存,去实例化B。

 

2、B实例化的过程中发现需要A,于是B先查一级缓存寻找A,如果没有,再查二级缓存,如果还没有,再查三级缓存,找到了A,然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A。

 

3、B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中的状态)。然后回来接着创建A,此时B已经创建结束,可以直接从一级缓存里面拿到B,去完成A的创建,并将A放到一级缓存。

 

A->B 把A放入到三级缓存中,然后去实例化B

B->A 去1、2、3级缓存中查找A,在三级缓存中找到A,把A从三级缓存中移到二级中,B初始化完成,放入到一级缓存中

A然后直接从一级缓存中拿到B。

 

spring中Bean的作用域

prototype:多实例:ioc容器启动并不会调用方法创建对象,每次获取会调用方法获取对象,所以每次获取的对象都是不一样的。

singleton:单实例(默认):ioc容器启动会调用方法创建对象放到ioc容器中,以后每次获取就是直接从容器中拿(map.get())

request:同一次请求创建一个实例

session:同一次会话创建一个实例

global Session:在一个全局的 HTTP Session 中,容器会返回该 Bean 的同一个实例。该作用域仅在使用 portlet context 时有效。

posted @ 2023-02-09 16:41  sugarstar  阅读(88)  评论(0)    收藏  举报