Spring IOC 学习笔记

1、IoC思想 .

如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。 

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

●谁依赖于谁:当然是应用程序依赖于IoC容器;

●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源;

●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

2、Spring初始化IoC容器的过程。

Spring 先加载beanDefinition到beanFactory中(用map存储,key是beanName),beanDefinition是bean数据结构的一种映射。然后处理beanDefiniton(怎么处理?)。完成bean注册beanFactory中。在完成之前,先预实例化那些单例bean(lazy-init为false的)。

3、IoC容器的初始化包括BeanDefinition的Resource定位,载入和注册。

(1)、定位:使用BeanDefinitionReader读取资源applicationContext.xml文件。

(2)、载入:读取xml文件中定义的Bean,然后表示成IoC容器内部的数据结构beanDefinition,包括xml中定义的和component_scan自动扫描到的带有@service,@controller,@dao注解的bean。

疑问?spring是用哪个类解析xml中定义的component_scan路径并scan所有bean的?

(3)、注册:向IoC容器注册这些BeanDefinition的过程。通过调用BeanDefinitionRegistry接口的实现来完成的,这个注册是把载入过程解析到的BeanDefinition向IoC容器进行注册。在IoC内部是通过一个HashMap来保存这些BeanDefinition数据的

4、IoC容器的初始化不包含Bean依赖注入的实现,一般依赖注入发生在应用第一次向容器通过getBean索取Bean时。但可以根据BeanDefinition信息中的Lazyinit属性来设定。即为false时,在容器初始化完成后,就预实例化。

    预实例化时,先从父类容器中判断是否有缓存,父类没有从子类容器判断是否有缓存。

public void preInstantiateSingletons() throws BeansException {
          if (this.logger.isInfoEnabled()) {
              this.logger.info("Pre-instantiating singletons in " + this);
          }
          synchronized (this.beanDefinitionMap) {
              // Iterate over a copy to allow for init methods which in turn register new bean definitions.
              // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
              List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
              for (String beanName : beanNames) {
                   RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//父类中获取。
                   if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                        if (isFactoryBean(beanName)) {
                             final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                             boolean isEagerInit;
                             if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                                  isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                                      public Boolean run() {
                                           return ((SmartFactoryBean<?>) factory).isEagerInit();
                                      }
                                  }, getAccessControlContext());
                             }
                             else {
                                  isEagerInit = (factory instanceof SmartFactoryBean &&
                                           ((SmartFactoryBean<?>) factory).isEagerInit());
                             }
                             if (isEagerInit) {
                                  getBean(beanName);
                             }
                        }
                        else {
                             getBean(beanName);
                        }
                   }
              }
          }
     }

 

5、Spring IoC对于不同scope的对象是怎么管理的?

    如果是single模式,那么直接取容器中的实例,那如果是原型模式,是每次getBean的时候,创建新实例吗?//TODO

6、为什么用Spring IoC而不是用工厂模式?

     使用工厂模式时,调用者仍然需要定位到工厂,使调用者和工厂耦合到一起。需要调用被调用者时直接IoC依赖注入。

7、几种注入的不同@Resource,@Autowired,@Qualier?

TODO

8、IOC的注入方式?

参见这里》Spring常用的三种注入方式  构造函数注入,Setter注入,基于注解的注入

 

参考:

Spring:源码解读Spring IOC原理

浅谈对Spring IOC以及DI的理解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值