spring源码分析1

我们知道,当:
AnnotationConfigApplicationContext al=new AnnotationConfigApplicationContext(appconfig.class);
//appconfig这个类是个spring配置类,加了@Configuration,@ComponentScan("packgename")这两个注解。
此方法初始化了spring容器

下面一探源码:


    /**
     * 这个构造方法需要传入一个被javaconfig注解了的配置类
     * 然后会把这个被注解了javaconfig的类通过注解读取器读取后继而解析
     * Create a new AnnotationConfigApplicationContext, deriving bean definitions
     * from the given annotated classes and automatically refreshing the context.
     * @param annotatedClasses one or more annotated classes,
     * e.g. {@link Configuration @Configuration} classes
     */
    public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        //annotatedClasses  appconfig.class
        //这里由于他有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法
        //在自己构造方法中初始一个读取器和扫描器
        this();
        register(annotatedClasses);//方法一
        refresh();//方法二
    }

先初始化父类的构造器,注意父类GenericApplicationContext的无参构造器是实例化BeanFactory
DefaultListableBeanFactory这个类就是spring的bean工厂

    /**
     * Create a new GenericApplicationContext.
     * @see #registerBeanDefinition
     * @see #refresh
     * 一个工厂
     */
    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }

然后this()调用自己的无参构造,无参构造代码如下:

    /**
     * 初始化一个bean的读取和扫描器
     * 何谓读取器和扫描器参考上面的属性注释
     * 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()
     * 去注册配置类(javaconfig),并调用refresh()方法刷新容器,
     * 触发容器对注解Bean的载入、解析和注册过程
     * 这种使用过程我在ioc应用的第二节课讲@profile的时候讲过
     * Create a new AnnotationConfigApplicationContext that needs to be populated
     * through {@link #register} calls and then manually {@linkplain #refresh refreshed}.
            */
    public AnnotationConfigApplicationContext() {
        /**
         * 父类的构造方法
         * 创建一个读取注解的Bean定义读取器
         * 什么是bean定义?BeanDefinition
         */
        this.reader = new AnnotatedBeanDefinitionReader(this);


        //可以用来扫描包或者类,继而转换成bd
        //但是实际上我们扫描包工作不是scanner这个对象来完成的
        //是spring自己new的一个ClassPathBeanDefinitionScanner
        //这里的scanner仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

首先看看构造方法里的第一个方法
this.reader = new AnnotatedBeanDefinitionReader(this);这句代码,构造方法参数是BeanDefinitionRegistry,而传的是this,表示AnnotationConfigApplicationContext是BeanDefinitionRegistry的子类。
AnnotatedBeanDefinitionReader这个类是BeanDefinition读取器,给它一个java类,它会解析成描述这个类的BeanDefinition,但是这个类只会解析加了注解的类,下面查看该方法的调用链:

    /**
     *  这里的BeanDefinitionRegistry registry是通过在AnnotationConfigApplicationContext
     *  的构造方法中传进来的this
     *  由此说明AnnotationConfigApplicationContext是一个BeanDefinitionRegistry类型的类
     *  何以证明我们可以看到AnnotationConfigApplicationContext的类关系:
     *  GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
     *  看到他实现了BeanDefinitionRegistry证明上面的说法,那么BeanDefinitionRegistry的作用是什么呢?
     *  BeanDefinitionRegistry 顾名思义就是BeanDefinition的注册器
     *  那么何为BeanDefinition呢?参考BeanDefinition的源码的注释
     * @param registry
     */
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
        this(registry, getOrCreateEnvironment(registry));
    }

再往里:

    /**
     * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry and using
     * the given {@link Environment}.
     * @param registry the {@code BeanFactory} to load bean definitions into,
     * in the form of a {@code BeanDefinitionRegistry}
     * @param environment the {@code Environment} to use when evaluating bean definition
     * profiles.
     * @since 3.1
     */
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
//      Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//      Assert.notNull(environment, "Environment must not be null");
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

你可能感兴趣的:(spring源码分析1)