Java开发从工作到原理--Spring IOC

 百度百科上关于控制反转的解释:

依赖查找是指spring中的哪些功能呢,按照百度百科中的解释,按我的理解是指Aware接口,例如BeanNameAware,BeanFactoryAware,EnvironmentAware,ApplicationContextAware,这些接口就是容器提供的API,我们写的bean需要实现这些接口,容器才会调用这些回调方法,让应用代码获得相关资源。

需要注意的是,Aware接口的调用一部分是由BeanFactory调用,一部分是由BeanPostProcessor调用的。

以上为BeanFactory接口上的注释说明,BeanFactory的实现类应该尽可能的支持bean的生命周期接口,具体的操作是在Bean创建过程中

如AbstractAutowireCapableBeanFactory.invokeAwareMethods方法

而EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware等接口方法的调用则在ApplicationContextAwareProcessor.postProcessBeforeInitialization方法中处理。

AbstractAutowireCapableBeanFactory.invokeAwareMethods方法要早于BeanPostProcess.postProcessBeforeInitialization方法调用。

@Autowired @Value @Resource@Inject(需要引入相应的jsr-330 jar包)都是日常开发工作中进行依赖注入的常用注解,是bean在创建之后进行初始化的过程中由各自对应的BeanPostProcess进行依赖注入的处理,主要是使用java的反射技术。

@Autowired @Value @Inject 由AutowiredAnnotationBeanPostProcessor.postProcessProperties方法处理

@Resource 由CommonAnnotationBeanPostProcessor.postProcessProperties方法处理,WebServiceRef注解和EJB注解并不是我们常用,且需要引入对应的jar包

Spring的依赖注入当然不是仅限于上述BeanPostProcessor,其实在Bean的创建过程中,BeanDefiniation中的信息也能起到依赖注入的作用,也就是说在不使用@Autowired这些注解的情况下,Spring依然支持给特定的bean注入特定的配置信息,或者依赖的bean。

以Dubbo的ServiceBean为例:

每一个标有@org.apache.dubbo.config.annotation.Service注解的bean,dubbo默认都会在启动时向BeanDefiniationRegistry中注册两个BeanDefiniation,一个是以bean本身的类型注册,一个是以ServiceBean的类型注册,ServiceBean中并没有使用@Autowired等注解,但是在向注册中心暴露接口的时候,我们能看到在@org.apache.dubbo.config.annotation.Service注解配置的provider,registry,monitor,protocol等对象都会被注入到ServiceBean实例中。那么我们来看看具体的处理方式:

@EnableDubbo注解上的@DubboComponentScan注解上通过@Import注解引入了实现ImportBeanDefinitionRegistrar的DubboComponentScanRegistrar,DubboComponentScanRegistrar向BeanDefinitionRegistry注册了ServiceAnnotationBeanPostProcessor(用于处理@org.apache.dubbo.config.annotation.Service)和ReferenceAnnotationBeanPostProcessor(用于处理@org.apache.dubbo.config.annotation.Reference),ServiceAnnotationBeanPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,在invokeBeanFactoryPostPorcesses时会被调用postProcessBeanDefinitionRegistry方法。在方法中会先扫描注册正常的bean,然后会获取到正常bean的BeanDefiniation用于创建注册ServiceBean的BeanDefinition。

 

对于Service注解中的provider,monitor,application,module,registry,protocol属性都是以RuntimeBeanReference的形式被添加到propertyValue中。

在ServiceBean实例的创建过程中AbstractAutowireCapableBeanFactory.doCreateBean到populateBean到applyPropertyValues方法中会将RuntimeBeanReference转换成对应的bean(具体由BeanDefinitionValueResolver进行转换,从beanFactory中获取到对应的bean),然后会通过BeanWrapper进行注入。也就是说,如果我们想使用这种依赖注入方式,需要在bean被实例化之前对bean的BeanDefinition进行修改,进行依赖注入属性配置。能达到这个功能的扩展点有BeanFactoryPostProcessor,BeanDefinitionRegistryPostProcessor,MergedBeanDefinitionPostProcessor,InstantiationAwareBeanPostProcessor等等

跟RuntimeBeanReference类似的还有很多,基本都由BeanDefinitionValueResolver进行转换:

以上为我目前了解到Spring中IOC的相关内容,依赖注入中byType byName,以及Qualifier注解,Bean作用域,单例、原型、Request,Session,GlobalSession的使用未作详细讨论,不过应该都能在上述提及的内容中找到。

IOC的好处

1、面向接口编程,解决代码之间耦合;

2、可以看成是池化技术跟缓存技术的结合,避免了对象多次创建造成的性能浪费;

3、对象不用多次创建,不会增加内存碎片,不会增加GC频率,减小造成OOM的几率;

IOC的坏处

1、初始内存占用率会比较高

2、会有比较多的非业务所需bean一直存在于内存中

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值