谈一谈Spring IOC

概念

IOC:Inversion of comtrol 控制反转,这个概念说起来很熟悉,理解起来还是有点困难的。要先弄清楚第一个问题:谁控制了谁?

public class Persion {
    private Order order;
    public Persion(Order order) {
        
        this.order = order;
    }
}

Persion 持有Order 的引用,在创建Persion的时候一定要有Order的对象传入才可以,这就是Order 控制着Persion.
现在要将这个控制权交给Persion,怎么做到的呢?IOC来管理所有的对象,Persion需要什么跟IOC要就可以,怎么要呢,通过依赖注入来要。
DI:Dependecy inversion 依赖注入,IOC是更加抽象的一层含义,可以只理解成一种思想,通过容器来控制对象的思想,真是的实现手段就是DI;
DI的三种实现方式:
接口注入:对代码有入侵不推荐
注解注入:@Autowired根据类型注入 @Resource 根据名称注入
setter注入:通过setter方法注入

容器启动流程

这个流程只是一个大概的流程方便我们更好的理解IOC
在这里插入图片描述

重要类的源码解析

AbstractApplicationContext的refresh()定义了整个spring启动的流程,有关bean的几个重要的步骤做了解释。

在这里插入图片描述跟踪 obtainFreshBeanFactory()
AbstractRefreshableApplicationContext
在这里插入图片描述
loadBeanDefinitions()这个方法中做的事情
如果是读取XML文件中的bean就会用到XmlBeanDefinitionReader 将xml文件的内容解析成BeanDefinition
如果是扫描注解创建bean 就会用到AnnotatedBeanDefinitionReader将扫描到的class文件 通过类的加载器加载到容器种转化成BeanDefinition
最后BeanDefinition保存在
在这里插入图片描述
接下来我们分析一下这个方法
this.finishBeanFactoryInitialization(beanFactory);

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    //先初始化ConversionService类型的bean  ConversionService这个是前端向controller传递参数的时候需要特殊处理的时候用的
    //例如时间字符串 勇敢date接受
    if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
        beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
    }

    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver((strVal) -> {
            return this.getEnvironment().resolvePlaceholders(strVal);
        });
    }
    //初始化LoadTimeWeaverAware类型的bean
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    String[] var3 = weaverAwareNames;
    int var4 = weaverAwareNames.length;

    for(int var5 = 0; var5 < var4; ++var5) {
        String weaverAwareName = var3[var5];
        this.getBean(weaverAwareName);
    }

    beanFactory.setTempClassLoader((ClassLoader)null);
    beanFactory.freezeConfiguration();
    // 预初始化 继续跟踪这个方法
    beanFactory.preInstantiateSingletons();
}

DefaultListableBeanFactory


public void preInstantiateSingletons() throws BeansException {
    if (this.logger.isTraceEnabled()) {
        this.logger.trace("Pre-instantiating singletons in " + this);
    }
    // 循环遍历所有非懒加载的beanDefinition
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    Iterator var2 = beanNames.iterator();

    while(true) {
        String beanName;
        Object bean;
        do {
            while(true) {
                RootBeanDefinition bd;
                do {
                    do {
                        do {
                            if (!var2.hasNext()) {
                                var2 = beanNames.iterator();

                                while(var2.hasNext()) {
                                    beanName = (String)var2.next();
                                    //如果已初始化完成这一步就可以直接获取到
                                    Object singletonInstance = this.getSingleton(beanName);
                                    // 如果是这个SmartInitializingSingleton类型的就在这里回调
                                    if (singletonInstance instanceof SmartInitializingSingleton) {
                                        SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                        if (System.getSecurityManager() != null) {
                                            AccessController.doPrivileged(() -> {
                                                smartSingleton.afterSingletonsInstantiated();
                                                return null;
                                            }, this.getAccessControlContext());
                                        } else {
                                            smartSingleton.afterSingletonsInstantiated();
                                        }
                                    }
                                }

                                return;
                            }

                            beanName = (String)var2.next();
                            bd = this.getMergedLocalBeanDefinition(beanName);
                        } while(bd.isAbstract());
                    } while(!bd.isSingleton());
                } while(bd.isLazyInit());
            // 如果是FactoryBean在beanName 前加 &
                if (this.isFactoryBean(beanName)) {
                    bean = this.getBean("&" + beanName);
                    break;
                }

                this.getBean(beanName);
            }
        } while(!(bean instanceof FactoryBean));

        FactoryBean<?> factory = (FactoryBean)bean;
        boolean isEagerInit;
        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
            SmartFactoryBean var10000 = (SmartFactoryBean)factory;
            ((SmartFactoryBean)factory).getClass();
            isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
        } else {
            isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
        }

        if (isEagerInit) {
            this.getBean(beanName);
        }
    }
}

这个方法中我们可以看到在初始化bean的时候factoryBean是要特殊处理的跟普通的Bean不一样。简单的Bean会通过getBean这个方法初始化,继续看这个方法

AbstractBeanFactory

protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
    String beanName = this.transformedBeanName(name);
    Object sharedInstance = this.getSingleton(beanName);
    Object bean;
    if (sharedInstance != null && args == null) {
        if (this.logger.isTraceEnabled()) {
            if (this.isSingletonCurrentlyInCreation(beanName)) {
                this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }

        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
    } else {
        if (this.isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            String nameToLookup = this.originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
            }

            if (args != null) {
                return parentBeanFactory.getBean(nameToLookup, args);
            }

            if (requiredType != null) {
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            }

            return parentBeanFactory.getBean(nameToLookup);
        }

        if (!typeCheckOnly) {
            this.markBeanAsCreated(beanName);
        }

        try {
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            this.checkMergedBeanDefinition(mbd, beanName, args);
            String[] dependsOn = mbd.getDependsOn();
            String[] var11;
            if (dependsOn != null) {
                var11 = dependsOn;
                int var12 = dependsOn.length;

                for(int var13 = 0; var13 < var12; ++var13) {
                    String dep = var11[var13];
                    if (this.isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }

                    this.registerDependentBean(dep, beanName);

                    try {
                        this.getBean(dep);
                    } catch (NoSuchBeanDefinitionException var24) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                    }
                }
            }

            if (mbd.isSingleton()) {
                sharedInstance = this.getSingleton(beanName, () -> {
                    try {
                        return this.createBean(beanName, mbd, args);
                    } catch (BeansException var5) {
                        this.destroySingleton(beanName);
                        throw var5;
                    }
                });
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            } else if (mbd.isPrototype()) {
                var11 = null;

                Object prototypeInstance;
                try {
                    this.beforePrototypeCreation(beanName);
                    prototypeInstance = this.createBean(beanName, mbd, args);
                } finally {
                    this.afterPrototypeCreation(beanName);
                }

                bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            } else {
                String scopeName = mbd.getScope();
                Scope scope = (Scope)this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }

                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        this.beforePrototypeCreation(beanName);

                        Object var4;
                        try {
                            var4 = this.createBean(beanName, mbd, args);
                        } finally {
                            this.afterPrototypeCreation(beanName);
                        }

                        return var4;
                    });
                    bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException var23) {
                    throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
                }
            }
        } catch (BeansException var26) {
            this.cleanupAfterBeanCreationFailure(beanName);
            throw var26;
        }
    }

    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            } else {
                return convertedBean;
            }
        } catch (TypeMismatchException var25) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
            }

            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    } else {
        return bean;
    }
}

到这里总的来说我们就分析完了,下面再总结一下

BeanFactory FactoryBean ApplicationContext

BeanFactory :是spring 框架的根基,是面向spring研发人员的,他的getBean发放是懒加载
功能:1.提供IOC的配置机制。
2. 包含bean的各种定义,便于实例化Bean
3. 建立bean之间的各种依赖关系
4. bean生命周期的管理
FactoryBean:是一个特殊的Bean,(在初始化的时候与普通的bean不一样),内部构造复杂的Bean,是一个工厂bean.
ApplicationContext :是面向spring使用者的。继承多个接口的高级容器,大多数功能的实现依赖的是DefaultListableBeanFactory这个类。

Bean的生命周期:

如果不是由spring;来管理的话我们的对象new->destory很简单.但是由spring来管理bean以后,bean的创建过程就比较复杂了,生命周期其实就是创建和销毁的过程.

  1. 从XML或者@中扫描到对象,通过BeanDefinitionReader读取bean的信息,加载,注册beanDefinition
  2. 注入Aware的依赖 实现这几个接口 BeanNameAware, BeanFactoryAware,
    ApplicationContextAware,
  3. 实现接口InitializingBean重写方法afterPropertiesSet()
  4. 执行通用的前置方法. 实现BeanPostProcessor接口的postProcessBeforeInitialization()方法.
  5. 通过注解执行init方法@Bean(initMethod = “init”),通过注解构造方法之后执行@PostConstruct
  6. 执行方法BeanPostProcessor.postProcessorAfterInitialization()
  7. 对象创建完毕
    对象的销毁
  8. 执行 DisposableBean.destory() 方法
  9. 执行自定义的destory方法或者 @PreDestory 标注的方法;
  10. 对象销毁完毕
    这些过程大家都可以手动试一下,验证一下的
public class MessageServiceImpl implements MessageService, BeanNameAware, BeanFactoryAware,
        ApplicationContextAware, InitializingBean, DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor {
    public void say() {
        System.out.println("hello");
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("MessageServiceImpl setBeanFactory");
    }

    public void setBeanName(String s) {
        System.out.println("MessageServiceImpl setBeanName"+s);
    }

    public void destroy() throws Exception {
        System.out.println("MessageServiceImpl destroy");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("MessageServiceImpl afterPropertiesSet");
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("MessageServiceImpl setApplicationContext");
    }


    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("postProcessBeanFactory====");
    }

    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessBeforeInitialization");
        return null;
    }

    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
        System.out.println("postProcessAfterInitialization");
        return null;
    }
}

Bean的作用域

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值