SpringIOC源码阅读—两大核心接口

作者: 激情的狼王 | 来源:发表于2017-11-13 17:37 被阅读0次

    IOC是spring最核心的理念,包括AOP也要屈居第二,那么IOC到底是什么呢,四个字,控制反转。
    实际开发中,使用例子如下:
    Person类:

    public class Person {
    
        public void work(){
            System.out.println("I am working");
        }
    }
    

    Company公司类

    public class Company {
    
        @Autowired
        public Person person;
        
        public void open(){
            person.work();
            System.out.println("I am opening");
        }
    }
    

    OK了,使用注解后,spring里的写法是这样的,是不是简单很多?或许你可能会说,这才减少了多少代码,但是事实上是,真正的项目中,不可能有这么简单的依赖关系,或许是2层,3层甚至N层。
    大致单步跟了下Spring IOC的初始化过程,整个脉络很庞大,初始化的过程主要就是读取XML里的bean的配置文件,并解析出来,最终生成bean的集合注册到Bean Factory中,在完成初始化的过程后,Bean们就在BeanFactory中蓄势以待地等调用了。
    首当其冲的是BeanFactory接口

    package org.springframework.beans.factory;
    
    import org.springframework.beans.BeansException;
    
    /*
     * @author Rod Johnson
     * @author Juergen Hoeller
     * @since 13 April 2001
     */
    public interface BeanFactory {
    
        String FACTORY_BEAN_PREFIX = "&";
    
    
        Object getBean(String name) throws BeansException;
    
    
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;
    
        
        <T> T getBean(Class<T> requiredType) throws BeansException;
    
        
        Object getBean(String name, Object... args) throws BeansException;
    
        
        boolean containsBean(String name);
    
        
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
    
        
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
    
        
        boolean isTypeMatch(String name, Class targetType) throws NoSuchBeanDefinitionException;
    
        
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
    
        
        String[] getAliases(String name);
    
    }
    

    容易理解的方法:

    getBean:从BeanFactory 里拿到一个实例
    containsBean:BeanFactory 是否包含某一个bean
    isSingleton,isPrototype:是否为单例,返回boolean类型

    根据getBean(String name)方法可以知道这个工厂维护着一个Map<String,BeanDefinition>来持有这些bean的实例,但是我们怎么知道这些bean之间的依赖关系和依赖层次呢?
    这个问题引出了第二个重量级的类BeanDefinition接口

    package org.springframework.beans.factory.config;
    
    import org.springframework.beans.BeanMetadataElement;
    import org.springframework.beans.MutablePropertyValues;
    import org.springframework.core.AttributeAccessor;
    
    
    public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    
    
        String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
    
    
        String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
    
    
        int ROLE_APPLICATION = 0;
    
    
        int ROLE_SUPPORT = 1;
    
    
        int ROLE_INFRASTRUCTURE = 2;
    
    
        String getParentName();
    
    
        void setParentName(String parentName);
    
    
        String getBeanClassName();
    
    
        void setBeanClassName(String beanClassName);
    
    
        String getFactoryBeanName();
    
        
        void setFactoryBeanName(String factoryBeanName);
    
        
        String getFactoryMethodName();
    
        
        void setFactoryMethodName(String factoryMethodName);
    
    
        String getScope();
    
        
        void setScope(String scope);
    
        
        boolean isLazyInit();
    
        
        void setLazyInit(boolean lazyInit);
    
        
        String[] getDependsOn();
    
        
        void setDependsOn(String[] dependsOn);
    
        
        boolean isAutowireCandidate();
    
        
        void setAutowireCandidate(boolean autowireCandidate);
    
        
        boolean isPrimary();
    
        
        void setPrimary(boolean primary);
    
    
        ConstructorArgumentValues getConstructorArgumentValues();
    
    
        MutablePropertyValues getPropertyValues();
    
    
        boolean isSingleton();
    
    
        boolean isPrototype();
    
        
        boolean isAbstract();
    
        
        int getRole();
    
        
        String getDescription();
    
        
        String getResourceDescription();
    
        
        BeanDefinition getOriginatingBeanDefinition();
    
    }
    

    仔细观看,能发现beanDefinition中有两个方法分别是String[] getDependsOn()void setDependsOn(String[] dependsOn),这两个方法就是获取依赖的beanName和设置依赖的beanName,这样就好办了,只要我们有一个BeanDefinition,就可以完全的产生一个完整的bean实例。
    本文介绍了IOC的两个接口类,宏观上概括了一下IOC的bean工厂定义和bean实例的定义,我相信不少人甚至不看源码都已经猜到spring是如何做的了。没错,就是让bean工厂持有一个Map<String,BeanDefinition>,这样就可以在任何时候我们想用哪个bean,取到它的bean定义,我们就可以创造出一个新鲜的实例,详细具体的IOC源码解析部分见后续文章。

    相关文章

      网友评论

        本文标题:SpringIOC源码阅读—两大核心接口

        本文链接:https://www.haomeiwen.com/subject/utbzmxtx.html