java|spring的对象管理
spring中的循环依赖 循环依赖 ,即一个类依赖了另一个类,但是另一个类又依赖第一个类
处理循环依赖关键是看第一个类依赖的类是什么作用域,以及是什么方式注入的
- 如果依赖的类是原型作用域,无法进行依赖注入,因为容器不会管理原型作用域的对象,自然也不会用来注入(注入之前必须要先能在容器中找到)
- 依赖的类是单例作用域,且是构造器方式中注入依赖,则会抛出异常
- 如果是setter方式注入依赖,则可以循环依赖,只需要将第二个类的注入和后续初始化在第一个类初始化完成之后调用即可
Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:
- BeanNameAware’s setBeanName
- BeanClassLoaderAware’s setBeanClassLoader
- BeanFactoryAware’s setBeanFactory
- 【java|spring的对象管理】EnvironmentAware’s setEnvironment
- EmbeddedValueResolverAware’s setEmbeddedValueResolver
- ResourceLoaderAware’s setResourceLoader (only applicable when
running in an application context)
- ApplicationEventPublisherAware’s setApplicationEventPublisher (only applicable when running in an application context)
- MessageSourceAware’s setMessageSource (only applicable when running in an application context)
- ApplicationContextAware’s setApplicationContext (only applicable
when running in an application context)
- ServletContextAware’s setServletContext (only applicable when running in a web application context)
- postProcessBeforeInitialization methods of BeanPostProcessors
- InitializingBean’s afterPropertiesSet
- a custom init-method definition
- postProcessAfterInitialization methods of BeanPostProcessors
- postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
- DisposableBean’s destroy
- a custom destroy-method definition
一个bean先是直接构造和设值注入
然后为在容器中为对应的BeanDefinition注册名字, 绑定各种关联的环境
然后就是容器中的BeanPostProcessors(另外一些bean)的初始化前置处理
如果bean自身实现了InitializingBean,会调用afterPropertiesSet()
再来是自定义的init方法
BeanPostProcessor的初始化后置处理
销毁的时候是
容器中的DestructionAwareBeanPostProcessors的销毁前置处理方法
如果bean自身实现了DisposableBean,会调用destroy
最后是自定义的destroy方法
基本流程与一个普通对象的实例化是一致的,
就是初始化时调用构造方法,设值注入,init方法
销毁时调用destroy方法
其他的增强功能还有对象自己实现的接口InitializingBean和DisposableBean
和容器中与之对应的BeanPostProcessor和DestructionAwareBeanPostProcessor的处理参与
FactoryBean BeanFactory是容器,而FactoryBean是用来产生bean的bean
既然容器本身就有产生bean的能力,那为什么还要用FactoryBean来产生bean呢?
答案是FactoryBean是可以实现对某一类对象的初始化的代理(也就是工厂方法本身的用处)
FactoryBean接口定义的方法如下
T getObject()
Class> getObjectType()
boolean isSingleton()
容器BeanFactory通过反射来实例化对象
当调用BeanFactory的getBean方法时, 如果有对应的FactoryBean(也就是Class和FactoryBean的getObjectType()相同,且满足相同作用域时),会调用FactoryBean的getObject()方法
这意味着在实际对象构造时可以在getObject()方法中加一层代理
实际上通过xml配置factory-method创建bean也就是实现了 FactoryBean
一些接口的用处 InitializingBean
void afterPropertiesSet() throws Exception
可以用来注入一些不需要spring容器管理的依赖的值,比如一个string(在纯粹使用注解和自动注入依赖的场景下能做一些补充),也可以用来做一些日志之类的处理
通过xml配置init-method也就是实现了InitializingBean,destroy-method同理
注解@PostConstruct和@PreDestroy的处理和InitializingBean类似,可以混用
BeanPostProcessor
Object postProcessBeforeInitialization(Object bean,
String beanName)
throws BeansExceptionObject postProcessAfterInitialization(Object bean,
String beanName)
throws BeansException
这个接口的用处很广泛,因为该接口的处理针对的是所有容器创建的bean,能够获取bean的实例和beanName,可以筛选一些beanName做特殊处理,也可以实现像是自动检测@Autowired,@Componet这样的注解并处理的功能
spring内部的很多注解处理类都实现了该接口
总结 spring的Ioc容器实际上是集中和强化了对对象的生命周期的管理,并提供了多种方式为对象的创建和销毁提供了增强功能
其创建流程也保证了依赖注入的安全性
另一个核心功能AOP,可以看作是提供了方法调用的增强功能
整个spring的核心目的是增加对象的可管理性,以及提供对任意位置的功能增强的接口
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量