Spring IOC 源码解析之创建应用上下文(一)

Spring5.1.x版本,使用注解扫描的方式

代码示例

Message

package com.huang.sourcelearn;

import org.springframework.stereotype.Component;

@Component
public class Message {

	public Message() {
		System.out.println(123);
	}
}

Student

package com.huang.sourcelearn;

public class Student {

    private String name;

    public Student() {
        this.name = "hsz";
    }

}

Config

package com.huang.sourcelearn;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.huang.sourcelearn")
public class Config {

    @Bean
    public Student student() {
        return new Student();
    }
}

MainTest

package com.huang.sourcelearn;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainTest {

	public static void main(String[] args) {
		ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
		Config config = applicationContext.getBean(Config.class);
		System.out.println(config);
		System.out.println(applicationContext.getBean(Message.class));
		System.out.println(applicationContext.getBean(Student.class));
	}
}

运行结果
在这里插入图片描述

源码解析

从main方法中创建AnnotationConfigApplicationContext开始分析。

创建AnnotationConfigApplicationContext分析

AnnotationConfigApplicationContext构造方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    //调用无参构造函数,会先调用父类GenericApplicationContext的构造函数
    //父类的构造函数里面就是初始化DefaultListableBeanFactory,并且赋值给beanFactory
    this();
    // 将annotatedClasses作为bd注册到容器中
    register(annotatedClasses);
    refresh();
}

public AnnotationConfigApplicationContext() {
    // 主要是为了解析带有注解的bean的beanDefinition,
    // 注册时需要传入带有注解的类对象或类对象数组
    this.reader = new AnnotatedBeanDefinitionReader(this);
    // 而这个是为了扫描带有注解的类,注册为beanDefinition
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

public void register(Class<?>... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    // 使用reader来注册
    this.reader.register(annotatedClasses);
}
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;
    
    public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}
}

首先会自己本身的无参构造方法,而由于java的特性,在执行无参构造方法之前又会调父类的无参构造方法,即GenericApplicationContext的无参构造方法,在这里面会为ApplicationContext中的BeanFactory实例化,创建DefaultListableBeanFactory,最终对容器的操作都是委托给这个容器实例来完成。

之后才执行自己的无参构造方法,在该方法里会实例化两个类,一个是读取注解的Bean定义读取器AnnotatedBeanDefinitionReader,一个是扫描类路径下的Bean定义的扫描器ClassPathBeanDefinitionScanner。

先看下AnnotatedBeanDefinitionReader实例化时做了啥事

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    this(registry, getOrCreateEnvironment(registry));
}

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;
    // 跟@Condition相关的,先放着
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    // 看方法名就知道该方法是注册注解配置相关的processor的
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

AnnotationConfigUtils

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
}

/**
 * 注册所有注解相关的后置处理器
 */
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    // 先转成DefaultListableBeanFactory类型
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            // 主要用来解析@Order和@Priority
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            // 主要用来处理@Autowired依赖注入的,判断bean是否匹配的,是否可以注入的,
            // 在后面解析依赖注入时会用到
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

    // 注册ConfigurationClassPostProcessor,解析加了@Configuration的配置类,
    // 还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解,
    // 是最为重要的BeanFactory后置处理器之一
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册AutowiredAnnotationBeanPostProcessor,顾名思义就是用来处理@Autowired和@Value注解的
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册CommonAnnotationBeanPostProcessor,用来处理公共注解,比如@PostConstruct和@PreDestroy还有@Resource等
	// jsr250Present的值是判断是否有javax.annotation.Resource
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册PersistenceAnnotationBeanPostProcessor,用来处理jpa的
	// jpaPresent就是判断是否存在PersistenceAnnotationBeanPostProcessor这个类,所以需要引入spring-orm的包,没有引入的话则spring不会注册这个类
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 注册EventListenerMethodProcessor,用来处理@EventListener注解
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    // 注册DefaultEventListenerFactory
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
}

主要是注册了一些跟注解相关的后置处理器。这几个后置处理器都是通过registerPostProcessor方法注册

private static BeanDefinitionHolder registerPostProcessor(
    	BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(beanName, definition);
    return new BeanDefinitionHolder(definition, beanName);
}

注意,虽然说的是注册后置处理器,但其实就是注册成普通的bean定义,还不在后置处理器缓存中

在前面我们知道这个BeanDefinitionRegistry就是DefaultListableBeanFactory

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    	throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            // beanDefinition先校验下
            ((AbstractBeanDefinition) beanDefinition).validate();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Validation of bean definition failed", ex);
        }
    }

    // 从beanDefinitionMap获取该beanDefinition
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
        // 如果已经存在同名的bean定义,则要判断是否允许覆盖,不允许覆盖则抛异常
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
        }
        else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isInfoEnabled()) {
                logger.info("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
            }
        }
        else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                             "' with a different definition: replacing [" + existingDefinition +
                             "] with [" + beanDefinition + "]");
            }
        }
        else {
            if (logger.isTraceEnabled()) {
                logger.trace("Overriding bean definition for bean '" + beanName +
                             "' with an equivalent definition: replacing [" + existingDefinition +
                             "] with [" + beanDefinition + "]");
            }
        }
        // 将旧的bean定义覆盖了
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }
    // 缓存中还不存在该bean定义
    else {
        // 检查这个工厂的 bean 创建阶段是否已经开始,即在此期间是否有任何 bean 被标记为已创建
        if (hasBeanCreationStarted()) {
            // Cannot modify startup-time collection elements anymore (for stable iteration)
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                removeManualSingletonName(beanName);
            }
        }
        else {
            // 将bean定义添加进缓存
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    // todo
    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
    }
}

接下来看下实例化ClassPathBeanDefinitionScanner

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    this(registry, true);
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
                                      Environment environment) {

    this(registry, useDefaultFilters, environment,
         (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
                                      Environment environment, @Nullable ResourceLoader resourceLoader) {

    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;

    if (useDefaultFilters) {
        // 注册默认的扫描类过滤器,加了特定的注解会被扫描到:
        // @Component、@Repository、@Service、@Controller、@ManagedBean、@Named
        registerDefaultFilters();
    }
    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}

registerDefaultFilters调用父类ClassPathScanningCandidateComponentProvider的方法。主要就是注册了默认的扫描类过滤器,加了特定的注解会被扫描到:@Component、@Repository、@Service、@Controller、@ManagedBean、@Named。

/**
 * 为@Component注册默认过滤器。
 * 这将隐式注册所有具有@Component元注释的注释,包括@Repository 、 @Service和@Controller型注释。
 * 还支持 Java EE 6 的javax.annotation.ManagedBean和 JSR-330 的javax.inject.Named注释(如果可用)。
 *
 */
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
	// 这里只需要添加扫描@Component的过滤器,因为@Repository 、 @Service和@Controller注解都被@Component注解标注了
	this.includeFilters.add(new AnnotationTypeFilter(Component.class));
	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
	// 下面两个都需要引入相关的jar包
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
		logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
	}
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
		logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
	}
	catch (ClassNotFoundException ex) {
		// JSR-330 API not available - simply skip.
	}
}

主要就是添加一个扫描@Component的过滤器。

接下来主要就是看refresh刷新容器,refresh主要逻辑在AbstractApplicationContext类中。
留在下一篇Spring IOC 源码解析之refresh(二)分析。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值