spring源码 IOC容器实现(2)

x33g5p2x  于2021-08-23 转载在 Spring  
字(52.7k)|赞(0)|评价(0)|浏览(508)

二spring源码 IOC容器实现

2.1整体设计

spring容器的整体设计流程如上面的UML图;

  • 顶级类BeanFacoty, 定义了bean的相关规范;

  • 二级类 HierarchicalBeanFactory 和 ListableBeanFactory 对 BeanFacoty 的功能进行了扩展;

  • ApplicationContext 作为整个容器的中央接口,起着至关重要的作用,为整个容器的启动到配置都提供了功能;

  • ConfigurableApplicationContext 实现了 ApplicationContext ,所有的资源加载功能都在这个类中进行配置;

  • 后面的类都是具体的子类,使容器功能更加完善;

2.2 IOC容器初始化(配置类注入)

根据上节源码搭建的测代码,就源码进行调试;

	public static void main(String[] args) {
		// 获取容器
		ApplicationContext ac =new AnnotationConfigApplicationContext(SysConfig.class);
		// 获取 bean
		SysUser user = (SysUser) ac.getBean("sysUser");
		System.out.println(user.toString());
	}

进入如下所示构造的方法,首先会调用this()方法,也就是调用构造方法;

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();//初始化构造器
		register(componentClasses);
		refresh();
	}

AnnotationConfigApplicationContext容器构造器如下,重点核心步骤就是 创建 AnnotatedBeanDefinitionReader,和ClassPathBeanDefinitionScanner;

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
	// 适配器,便捷的注册bean
	private final AnnotatedBeanDefinitionReader reader;
	//扫描classPath下bean,并注册
	private final ClassPathBeanDefinitionScanner scanner;
	// 构造器
	public AnnotationConfigApplicationContext() {
        //开始步骤	
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
        // 注入 注解需要的BeanDefinition
		this.reader = new AnnotatedBeanDefinitionReader(this);
        //结束步骤
		createAnnotatedBeanDefReader.end();
        //
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
    //.......
}   

注解方式初始化解析bean准备工作

AnnotatedBeanDefinitionReader的方法如下里面就是调用了构造方法,registry 就是 AnnotationConfigApplicationContext ; AnnotationConfigApplicationContext 实现了BeanDefinitionRegistry;

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

进入 构造器先是 getOrCreateEnvironment方法,其是 获取 环境信息;如果BeanDefinitionRegistry 有环境信息就获取,否则返回标准环境信息(JVM的系统变量);

	private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		if (registry instanceof EnvironmentCapable) {
			return ((EnvironmentCapable) registry).getEnvironment();// 返回当前registry的环境
		}
		return new StandardEnvironment();// 返回标准环境
	}

看下标准环境属性就是jvm和系统环境变量

public class StandardEnvironment extends AbstractEnvironment {

	/**系统环境变量名 */
	public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";

	/** jvm系统属性名 */
	public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";


	// 自定义适用于标准环境的属性
	@Override
	protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(
				new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
		propertySources.addLast(
				new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
	}

}

环境信息是什么?其是一些应用的配置信息,比如一些日志,profile,系统属性等,详细如下;

接口可以看EnvironmentCapable

public interface EnvironmentCapable {

	/**
	 * Return the {@link Environment} associated with this component.
	 */
	Environment getEnvironment();

}

进入 AnnotatedBeanDefinitionReader 构造方法 ;重点看 ConditionEvaluator 我称为这个为步骤一 和 registerAnnotationConfigProcessors 我称为这个为步骤二;

public class AnnotatedBeanDefinitionReader {

	private final BeanDefinitionRegistry registry;// 注册表
	// 如果未指定bean名称就会根据驼峰类名生成bean名称
	private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
	// 监测注解的作用域 ;AnnotationScopeMetadataResolver 实现 ScopeMetadataResolver (函数式的策略接口)
	private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
	// 评估注解
	private ConditionEvaluator conditionEvaluator;
	//...........
	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);
	}
	//...........
}    

步骤一 : 进入ConditionEvaluator

class ConditionEvaluator {

	private final ConditionContextImpl context;

	public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
			@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
		//创建实例
		this.context = new ConditionContextImpl(registry, environment, resourceLoader);
	}
}	

进入 ConditionContextImpl可以看到首先就是要初始化 deduceBeanFactory(registry) 方法 , 其次是 deduceResourceLoader(registry) ;

private static class ConditionContextImpl implements ConditionContext {
		// registry 知识执行者称为注册表,实际上就是spring容器
		@Nullable
		private final BeanDefinitionRegistry registry;
		// beanFactory
		@Nullable
		private final ConfigurableListableBeanFactory beanFactory;
		// 环境变量
		private final Environment environment;
		// 资源加载器
		private final ResourceLoader resourceLoader;
		// 类加载器
		@Nullable
		private final ClassLoader classLoader;
		// 构造器实例化
		public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
				@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {

			this.registry = registry;
             //获取 BeanFactory
			this.beanFactory = deduceBeanFactory(registry);
            // 这边是有环境变量进来
			this.environment = (environment != null ? environment : deduceEnvironment(registry));
            //这边ResourceLoader资源加载器是空的需要调用方法
			this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
            // 类加载器
			this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
		}
    // ........
}   

deduceResourceLoader(registry) 方法 的目的就是 获取 BeanFactory;

	private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
			if (source instanceof ConfigurableListableBeanFactory) {
				return (ConfigurableListableBeanFactory) source;
			}
			if (source instanceof ConfigurableApplicationContext) {
                //获取 BeanFactory
				return (((ConfigurableApplicationContext) source).getBeanFactory());
			}
			return null;
		}

UML图如下

ResourceLoader 本质上还是 BeanDefinitionRegistry 注册表

		private ResourceLoader deduceResourceLoader(@Nullable BeanDefinitionRegistry source) {
			if (source instanceof ResourceLoader) {
				return (ResourceLoader) source;
			}
			return new DefaultResourceLoader();
		}

deduceClassLoader 方法获取的是beanFactory 的类加载器

		@Nullable// 类加载器获取的是beanFactory的类加载器
		private ClassLoader deduceClassLoader(@Nullable ResourceLoader resourceLoader,
				@Nullable ConfigurableListableBeanFactory beanFactory) {
			// 这边 resourceLoader 为空
			if (resourceLoader != null) {
				ClassLoader classLoader = resourceLoader.getClassLoader();
				if (classLoader != null) {
					return classLoader;
				}
			}
			if (beanFactory != null) {
				return beanFactory.getBeanClassLoader();// 获取beanFactory的类加载器
			}
			return ClassUtils.getDefaultClassLoader();
		}

步骤二: registerAnnotationConfigProcessors(this.registry)

registerAnnotationConfigProcessors 注册各种相关的 processors;

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
		registerAnnotationConfigProcessors(registry, null);//注册processors
	}

进入registerAnnotationConfigProcessors(registry, null)

其是注册PostProcessor, 而且存放在 map中,主要还是看注入了哪些PostProcessor;

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(// 注册注解相关的processors
			BeanDefinitionRegistry registry, @Nullable Object source) {
		// 获取底层的beanFactory即 DefaultListableBeanFactory
		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}
		// BeanDefinitionHolder 持有 BeanDefinition 的名称和别名
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		// 判定是否包含bean
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);//设置 RootBeanDefinition
			def.setSource(source);// 设置source
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));// 真正的注册beanDefine
		}
	// .......... 一堆的判定注册 PostProcessor

		return beanDefs;
	}

查看下beanDefs 中的内容,应该都是注解需要的PostProcessor

这些PostProcessor 都定义在 AnnotationConfigUtils,主要是 BeanPostProcessor BeanFactoryPostProcessor和AutowireCandidateResolver等;

继续看 registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)

BeanDefinitionHolder 才是真正的 bean 信息的持有者;存放 BeanDefinition,beanName,aliases

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

		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//设置角色
		registry.registerBeanDefinition(beanName, definition);//注册bean
		// 反回 BeanDefinitionHolder(存放 BeanDefinition,beanName,aliases)
		return new BeanDefinitionHolder(definition, beanName);
	}

重点是注册bean : registry.registerBeanDefinition(beanName, definition); 即此时才向 注册表BeanDefinitionRegistry 中注入 RootBeanDefinition,这些都是注解需要的 BeanDefinition;并非 我们的用户 bean;

不知道你们看起来清晰不,回顾一下整个注解注入 BeanDefinition 的流程

扫描类路径下的bean

ClassPathBeanDefinitionScanner 是扫描classpath 下 的 bean注入容器;进入构造器

 // 加载bean
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
		this(registry, true);
	}

再将纳入构造器里面还是调用了一个构造器;

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

这边 getOrCreateEnvironment(registry) 方法我们之前说明就是为了获取环境如果没有配置则就是获取jvm系统环境;useDefaultFilters 是 个布尔类型,默认就是调用默认的过滤器;

进入三个参数的构造器

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

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

registry 是属于 ResourceLoader 的实例,所以不为空;

继续跟踪

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

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;
		// true
		if (useDefaultFilters) {
			registerDefaultFilters();// 设置默认过滤器
		}
		setEnvironment(environment);// 设置环境
		setResourceLoader(resourceLoader);// 设置资源加载器
	}

我们主要看下 设置默认过滤器,到底spring是在过滤什么类型的注解;

public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
	// 默认的资源路径
	static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";

	// 日志
	protected final Log logger = LogFactory.getLog(getClass());
	// 默认的资源路径
	private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
	// 包括的注解
	private final List<TypeFilter> includeFilters = new LinkedList<>();
	// 排除的注解
	private final List<TypeFilter> excludeFilters = new LinkedList<>();
    // ...........

protected void registerDefaultFilters() {// 为@Component 注解注入过滤器
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));// LinkedList 加入 Component 注解
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();// 获取资源加载器
		try {// 向过滤器 添加 ManagedBean 注解
			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 {// 向过滤器 添加 Named 注解
			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.
		}
	}
    // ............

如上源码中includeFilters 和 excludeFilters 都是LinkedList 充当过滤器; includeFilters 表示包含的注解才会被扫描 ,这边就是 @Component , @ ManagedBean, @Named 注解excludeFilters 表示排除在外的注解,不会被扫描至spring容器;当然这边还无法看见扫描的具体源码,我们后面再看;

我们 搜索Controller 注解,发现类上 也是 @Component 注解, 其余的 @Repository,@Service 本质上也是 @Component 注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

	// 逻辑层注解
   @AliasFor(annotation = Component.class)
   String value() default "";

}

回忆一下 ClassPathBeanDefinitionScanner 这个流程所作的事

注册bean

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();//初始化构造器
		register(componentClasses);
		refresh();
	}

回到第一个构造器;我们这次看 register(componentClasses); 方法

	@Override
	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		// 步骤开启
		StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
				.tag("classes", () -> Arrays.toString(componentClasses));
		//注册一个或多个含有@component注解的的类
		this.reader.register(componentClasses);
		// 步骤结束
		registerComponentClass.end();
	}

核心方法this.reader.register(componentClasses); , 就是扫描 含有 @Component注解的类 ,知识追寻这边就是 SysConfig ,因为在配置类上加了 @Configuration 注解,里面也是 @Component注解;

reader 是 AnnotatedBeanDefinitionReader; 进入方法内部进行循环注入 含有@Component注解的类;

public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);//迭代注入含有@component注解的类
		}
	}

进入 registerBean(componentClass) 内部;

public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null, null);
	}

进入 doRegisterBean(beanClass, null, null, null, null);

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {
		// 为@Compoent的类创建AnnotatedGenericBeanDefinition,内部是设置bean的过程
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { //1 基于 @Conditional 注解是否跳过加载
			return;
		}

		abd.setInstanceSupplier(supplier);// 创建bean 实例的回调
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);// 2默认单例
		abd.setScope(scopeMetadata.getScopeName());// 设置作用域
   		 // 3返回beanName(如果注解上有指定beanName就回返否则根据简单类名作为beanName)
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		// 4对 AnnotatedGenericBeanDefinition 的一些配置,如懒加载,primary, bean依赖等
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);// 设置primary
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);// 设置懒加载
				}
				else {
                    //设置Qualifier限定
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}
		// BeanDefinitionHolder 我们很熟悉,存放 beanName BeanDefinition alias
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    	// 代理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    	// 5注入BeanDefinition
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

第一个值得说的是this.conditionEvaluator.shouldSkip(abd.getMetadata()) 基于 @Conditional 注解是否跳过加载bean;最终会走到shouldSkip 方法,如果元注解中包含 @Conditional true, 否则返回false;

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {// 基于 @Conditional 注解是否跳过
		if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
			return false;
		}
		//......
}		

第二个是this.scopeMetadataResolver.resolveScopeMetadata(abd) 默认就是单例模式,可以看接口 ScopeMetadata;

public class ScopeMetadata {
	// 默认单例
	private String scopeName = BeanDefinition.SCOPE_SINGLETON;
	// 代理模式
	private ScopedProxyMode scopedProxyMode = ScopedProxyMode.NO;
	//.............
}	

内部走的是resolveScopeMetadata(BeanDefinition definition)方法, 目的就是获取元数据信息,如果有指定@scope作用域 则 设置指定值,否则默认单例;

// 获取元数据	
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
		ScopeMetadata metadata = new ScopeMetadata();
        // 默认 singleton MOde 为 NO
		if (definition instanceof AnnotatedBeanDefinition) {
			AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
            // 获取 @scope注解的值
			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
					annDef.getMetadata(), this.scopeAnnotationType);
			// @scope属性值不为空
            if (attributes != null) {
                //获取值
				metadata.setScopeName(attributes.getString("value"));
                // 获取代理模式
				ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
				//代理模式等于默认模式
                if (proxyMode == ScopedProxyMode.DEFAULT) {
					//设置proxyMode为NO
                    proxyMode = this.defaultProxyMode;
				}
                // 设置proxyMode
				metadata.setScopedProxyMode(proxyMode);
			}
		}
    	// 返回元数据信息
		return metadata;
	}

最终元数据信息如下

第三个是获取bean的名称, 未指定bean名称的情况下,默认简单类名(小写开头驼峰的名字);

	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
        // 扫描类上的注解,如果有指定beanName 就返回
		if (definition instanceof AnnotatedBeanDefinition) {
			String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
			if (StringUtils.hasText(beanName)) {
				// Explicit bean name found.
				return beanName;
			}
		}
		// 获取beanName
		return buildDefaultBeanName(definition, registry);
	}

最后会走到buildDefaultBeanName 方法获取简单类名作为bean的名称

	protected String buildDefaultBeanName(BeanDefinition definition) {
		String beanClassName = definition.getBeanClassName();
		Assert.state(beanClassName != null, "No bean class name set");
		String shortClassName = ClassUtils.getShortName(beanClassName);
		return Introspector.decapitalize(shortClassName);
	}

getShortName 方法就是 对 全类名进行字符串切割

	public static String getShortName(String className) {
		Assert.hasLength(className, "Class name must not be empty");
		int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR);
		int nameEndIndex = className.indexOf(CGLIB_CLASS_SEPARATOR);
		if (nameEndIndex == -1) {
			nameEndIndex = className.length();
		}
		String shortName = className.substring(lastDotIndex + 1, nameEndIndex);
		shortName = shortName.replace(INNER_CLASS_SEPARATOR, PACKAGE_SEPARATOR);
		return shortName;
	}

第四个是 对 AnnotatedGenericBeanDefinition 的熟悉配置,比如 懒加载@lazy,依赖@dependsOn,首要加载@Primary等;

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
		 // 设置懒加载
    	if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
    	// 元注解metadata 就是类上的注解
		else if (abd.getMetadata() != metadata) {
			lazy = attributesFor(abd.getMetadata(), Lazy.class);
			if (lazy != null) {
				abd.setLazyInit(lazy.getBoolean("value"));
			}
		}
		// 设置Primary
		if (metadata.isAnnotated(Primary.class.getName())) {
			abd.setPrimary(true);
		}
    	// 设置bean依赖
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}
		// 设置bean角色
		AnnotationAttributes role = attributesFor(metadata, Role.class);
		if (role != null) {
			abd.setRole(role.getNumber("value").intValue());
		}
    	//设置描述
		AnnotationAttributes description = attributesFor(metadata, Description.class);
		if (description != null) {
			abd.setDescription(description.getString("value"));
		}
	}

最后面我们看下 注入bean这个方法调用BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); 从BeanDefinitionHolder 获取 BeanDefinition信息 ,注入到注册表BeanDefinitionRegistry,如果为指定别名就使用bean名称,否则使用别名;

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// 注入BeanDefinition

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);//指定别名
			}
		}
	}

BeanDefinition 的注册最后走的实现类DefaultListableBeanFactory中registerBeanDefinition 的方法;

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");
		// 对bean进行校验
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}
		// 获从map中取bean
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    	// 如果beanDefinition已经存在
		if (existingDefinition != null) {
				// 不允许 beanDefinition 同名
            	if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
            // 角色判定
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
			
				if (logger.isInfoEnabled()) {
					// 省略日志
				}
			}
            // 已存在的beanDefinition不相等
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					// 省略日志
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					// 省略日志
				}
			}
			// 将bean放入map
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
            // 监测 factory 的  beanDefinition 已经是否处于创建阶段
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
                    // 将bean的名称,beanDefinition注入map
					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的名称,beanDefinition注入map
				this.beanDefinitionMap.put(beanName, beanDefinition);
                // 将 bean 的名称注入ArrayList
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
		// 如果已经存在重新设置所有的BeanDefinition
		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);// 重新设置所有的BeanDefinition
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

最终 的BeanDefinition 是放在ConcurrentHashMap中,默认初始容量 256;

	/** Map of bean definition objects, keyed by bean name. */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

回顾下注册bean的过程都做了什么

容器扩展功能

回到刚刚进入构造器的时候我们看refresh() 方法;refresh() 方法有点像电脑重启的意思,spring容器在启动运行的时候会重新加载和扩展一些配置,保证容器的正常运行;

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();//初始化构造器
		register(componentClasses);
		refresh();
	}

进入 refresh方法具体看看

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {// 同步锁
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// 步骤 refresh

			// 1准备refresh,里面是AtomicBoolean修饰的标志变量active和 closed
			prepareRefresh();

			// 2告诉子类refresh bean factory,其实就是获取 bean factory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3为使用容器配置bean factory
			prepareBeanFactory(beanFactory);

			try {
				//  设置 post-processing(后处理)
				postProcessBeanFactory(beanFactory);
				// 开启步骤 post-process
				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// 4调用factory processors后处理
				invokeBeanFactoryPostProcessors(beanFactory);

				//  注册拦截bean 处理器
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				//  5初始化容器信息,国际化处理
				initMessageSource();

				// 6初始化容器事件
				initApplicationEventMulticaster();

				// 初始化特殊的bean(内部没做事情)
				onRefresh();

				//  7监测并注入监听器
				registerListeners();
				// 8初始化所有遗留(non-lazy-init)的单例
				finishBeanFactoryInitialization(beanFactory);
				// 9结束refresh
				finishRefresh();
			}

			catch (BeansException ex) {
				// 省略日志
				// 摧毁已经创建的单例
				destroyBeans();
				// 重置标志位
				cancelRefresh(ex);
				// Propagate exception to caller.
				throw ex;
			}
			finally {
				resetCommonCaches();// 清空缓存
				contextRefresh.end();// 步骤 refresh 结束
			}
		}
	}

1准备refresh,prepareRefresh(); 方法,其主要功能就是设置启动事件,激活标志位并且执行和初始化属性资源

protected void prepareRefresh() {//准备refresh,设置启动事件,激活标志位并且执行和初始化属性资源
   // Switch to active.
   this.startupDate = System.currentTimeMillis();// 时间戳
   this.closed.set(false);// 原子类标志位
   this.active.set(true);
	// 省略日志
   // 初始化 placeholder 属性资源(里面什么都没做)
   initPropertySources();// 

   // 校验系统环境需要的属性
   getEnvironment().validateRequiredProperties();

   //............
}

这里的 initPropertySources ,什么东西都没有做,但其子类有;

protected void initPropertySources() {
		// For subclasses: do nothing by default.
	}

getEnvironment().validateRequiredProperties() 就是对系统需要的变量进行校验;

	public void validateRequiredProperties() {
		MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();// 属性未找到异常
		for (String key : this.requiredProperties) {
			if (this.getProperty(key) == null) {// 如果系统属性为空,就添加属性
				ex.addMissingRequiredProperty(key);
			}
		}
		if (!ex.getMissingRequiredProperties().isEmpty()) {
			throw ex;
		}
	}

**2 获取 bean factory **;

进入obtainFreshBeanFactory 方法,是关于 子类 refresh bean 的操作,本质上是获取BeanFactory ;

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {// refresh bean factory
		refreshBeanFactory();// 本质上没做什么
		return getBeanFactory();// 获取bean
	}

我们先看 refreshBeanFactory();该方法在注解配置中本质上未做一些有意义的事情;

	protected final void refreshBeanFactory() throws IllegalStateException {
		if (!this.refreshed.compareAndSet(false, true)) {// cas操作只能refresh一次
			throw new IllegalStateException(
					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
		this.beanFactory.setApplicationStartup(this.getApplicationStartup());// 设置启动
		this.beanFactory.setSerializationId(getId());// factory 序列化id
	}

其次再看 getBeanFactory(); 方法,这个获取 beanFactory 的方法属于 GenericApplicationContext 容器

	// 获取BeanFactory
	@Override
	public final ConfigurableListableBeanFactory getBeanFactory() {
		return this.beanFactory;
	}

防止忘记,我们再看一下UML图,GenericApplicationContext 容器 是 ConfigurableListableBeanFactory 的子类;

3为使用容器配置bean factory; 主要是对 bean factory 功能的扩展,比如SPEL表达式支持,

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// bean factory 使用 容器的的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
    	// SPEL表达式支持
		if (!shouldIgnoreSpel) {
			beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		}
    	// 与 BeanWrapper 有关
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		//为容器添加 ApplicationContextAwareProcessor
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    	// 忽略自动装配
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationStartup.class);

		// 为自动装配依赖注入值
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 添加后处理器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		//准备织入
		if (!IN_NATIVE_IMAGE && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注入环境属性bean
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
		if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
			beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
		}
	}

我们具体分析下上面相关的源码:

有关SPEL表达式定义和设置可以看 StandardBeanExpressionResolver 解析器;

public class StandardBeanExpressionResolver implements BeanExpressionResolver {

	/** Default expression prefix: "#{". */	//前缀
	public static final String DEFAULT_EXPRESSION_PREFIX = "#{";

	/** Default expression suffix: "}". */ // 后缀
	public static final String DEFAULT_EXPRESSION_SUFFIX = "}";


	private String expressionPrefix = DEFAULT_EXPRESSION_PREFIX;

	private String expressionSuffix = DEFAULT_EXPRESSION_SUFFIX;
	// 表达式解析
	private ExpressionParser expressionParser;
	// 表达式缓存
	private final Map<String, Expression> expressionCache = new ConcurrentHashMap<>(256);
	// 评估
	private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache = new ConcurrentHashMap<>(8);
    // ..............
}	

有关spel表达式的配置可以看 SpelParserConfiguration;

public class SpelParserConfiguration {

	private static final SpelCompilerMode defaultCompilerMode;

	static {
		String compilerMode = SpringProperties.getProperty("spring.expression.compiler.mode");
		defaultCompilerMode = (compilerMode != null ?
				SpelCompilerMode.valueOf(compilerMode.toUpperCase()) : SpelCompilerMode.OFF);
	}


	private final SpelCompilerMode compilerMode;

	@Nullable
	private final ClassLoader compilerClassLoader;

	private final boolean autoGrowNullReferences;

	private final boolean autoGrowCollections;

	private final int maximumAutoGrowSize;
    //............
}    

为自动装配依赖注入值,本质上 是 写入 ConcurrentHashMap中;支持四种@Autowired注入

  • BeanFactory

  • ResourceLoader

  • ApplicationEventPublisher

  • ApplicationContext

public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
		Assert.notNull(dependencyType, "Dependency type must not be null");
		if (autowiredValue != null) {
			if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {
				throw new IllegalArgumentException("Value [" + autowiredValue +
						"] does not implement specified dependency type [" + dependencyType.getName() + "]");
			}
            // 是个 ConcurrentHashMap
			this.resolvableDependencies.put(dependencyType, autowiredValue);
		}
	}

4 调用factory processors后处理;首先会调用getBeanFactoryPostProcessors() 方法 返回一个list,里面存放了大量的 processors bean; 然后通过 invokeBeanFactoryPostProcessors 方法进行后处理;

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// 。。。。
	}

5初始化容器信息,国际化处理;主要是关于 messageSource 和父 消息源的设置;

protected void initMessageSource() {
    // 获取beanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	//如果beanFactory中包含 messageSource	
    if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            // 获取messageSource
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// 转为 父消息 HierarchicalMessageSource
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                // 如果父消息源为空则设置
				if (hms.getParentMessageSource() == null) {
					
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// 使用DelegatingMessageSource 作为消息源; 空消息
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
            // 注册消息源
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

6初始化容器事件;如果用户有定义了容器 事件 applicationEventMulticaster则使用 自定义,否则使用默认的SimpleApplicationEventMulticaster 简单事件;

protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    	// 包含事件 applicationEventMulticaster则使用
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			//....
		}
		else {// 如果容器中不包含创建简单事件
			SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			// 步骤simpleApplicationEventMulticaster.setApplicationStartup(getApplicationStartup());
			this.applicationEventMulticaster = simpleApplicationEventMulticaster;
            //注入事件
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			//......
		}
	}

7监测并注入监听器; 监听器这边没有好的例子可以判定调试,猜测是如果用户有自定义的监听器则使用,否则会加载spring内部默认的监听器;

protected void registerListeners() {// 注入监听器
		// Register statically specified listeners first.
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

8 初始化所有遗留(non-lazy-init)的单例;当 所有遗留的单例被初始化完成,那么beanFactory 的初始化操作也就结束了;

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//.........
		// 暂停使用 temporary ClassLoader
		beanFactory.setTempClassLoader(null);

		// 冻结 bean definition ,不期望bean发生改变
		beanFactory.freezeConfiguration();

		//初始化所有遗留(non-lazy-init) 的单例
		beanFactory.preInstantiateSingletons();
	}

9 结束refresh;源码中显示了初始化生命周期后处理器,这个是结束refresh的重点;

	//完成refresh,调用生命周期后处理器
	protected void finishRefresh() {
		//清除context-level 资源缓存
		clearResourceCaches();

		// 初始化生命周期后处理器
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// 发布事件给所有的监听器
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		if (!IN_NATIVE_IMAGE) {
			LiveBeansView.registerApplicationContext(this);
		}
	}

看下生命周期接口 原理定义了组件的生命周期;

public interface Lifecycle {

	// 开始组件运行
	void start();

	// 停止组件运行(component)
	void stop();

	// 监测组件是否正在运行
	boolean isRunning();

}

回顾一下 refresh()方法扩展了spring哪些功能

2.3 小结

从整个源码跟踪过程中我们知道了 spring 容器的一个初始化过程,先是初始化构造器 ,在 AnnotatedBeanDefinitionReader 中 为注解的解析bean做准备工作;在ClassPathBeanDefinitionScanner

类中扫描类class path 下的组件类,在这边还定义了默认过滤器,哪些注解类可以通过spring容器注入,哪些类不能被注入,并且配置了环境变量,资源加载器等;其次我们跟踪到了 register 方法,所有外部的bean都是在这边注入,并且还能根据@condition注解是否注入bean; 最后就是 refresh 方法,其是spring的扩展功能,比如SPEL表达式支持,消息处理,事件发布,监听器注入等等;如果感觉收益匪浅,就为作者点赞吧!!

2.4 IOC容器初始化(扫描方式)

上个小节中知识追寻者使用的是配置类注入方式;本次使用扫描基本包方式看看有何差异;测试代码如下

	public static void main(String[] args) {
		// 获取容器
		ApplicationContext ac =new AnnotationConfigApplicationContext("com.zszxz");
		// 获取 bean
		SysUser user = (SysUser) ac.getBean("sysUser");
		System.out.println(user.toString());
	}

进入构造器后如下代码所示,this()调用的构造器是辅助工作(为解析注解配置提供准备)与上小结内容无差异;

refresh()扩展方法也是;所以重点还是看 scan(basePackages) 方法是如何扫描基本包

	public AnnotationConfigApplicationContext(String... basePackages) {
        // 构造器初始化
		this();
        // 扫描基本包
		scan(basePackages);
        // 扩展
		refresh();
	}

进入scan(basePackages) 方法, 这边的 this.scanner 就是ClassPathBeanDefinitionScanner,扫描classpath下 bean的作用;

public void scan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
    	// 步骤扫描基本包开始
		StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan")
				.tag("packages", () -> Arrays.toString(basePackages));
		// 扫描基本包
    	this.scanner.scan(basePackages);
    	// 步骤扫描基本包结束
		scanPackages.end();
	}

继续跟踪 this.scanner.scan(basePackages); 方法, 又包了一层 doScan(basePackages); 方法

	public int scan(String... basePackages) {
        // 获取容器中已经注入bean Definition 的个数
		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
		// 扫描基本包
		doScan(basePackages);

		// 注解配置后处理器
		if (this.includeAnnotationConfig) {
			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
		}
		// 获取当前注入容器bean Definition的个数
		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
	}

调试进入 doScan(basePackages); 方法

	// 扫描基本包下bean
	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
         // 遍历基本包
		for (String basePackage : basePackages) {
            // 获取组件类
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
                //获取@Scope注解的值(Bean的作用域)
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);			
                //为Bean设置作用域
				candidate.setScope(scopeMetadata.getScopeName());
                // 获取bean名称
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
                    // bean的后处理,配置bean的作用域,懒加载等
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
                // 候选bean是否是注解bean
				if (candidate instanceof AnnotatedBeanDefinition) {
					// bean的后处理,配置bean的作用域,懒加载等
 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}// 判定是否是相同的bean
				if (checkCandidate(beanName, candidate)) {
                    ;// 创建 BeanDefinitionHolder
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName)
                    // 根据作用域设置代理
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    ;//加入集合
					beanDefinitions.add(definitionHolder)
                    //向容器注入 bean
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
        // 返回 beanDefinition 集合
		return beanDefinitions;
	}

整个扫描过程看下来 最重要的就是findCandidateComponents(basePackage); 寻找组件方法; 注入bean之前我们说过了,不再赘述;

	// 扫描 class path 下的 组件(带有@component注解的类)
	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
		}
		else {
            // 扫描基本包获取组件
			return scanCandidateComponents(basePackage);
		}
	}

继续看 scanCandidateComponents(basePackage);

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
            // 补充路径扫描class; packageSearchPath = classpath*:com/zszxz/**/*.class
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
            // 资源定位
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
            // 资源是个file协议文件
			for (Resource resource : resources) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);// 获取class元数据
						if (isCandidateComponent(metadataReader)) {//判定元数据是否在includeFilter过滤器规则范围中
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);
							//..........
		return candidates;
	}

我们这边先不看资源定位,以后再讨论,主要看 isCandidateComponent(metadataReader), spring是如何判定bean是否合格;

// 给定的class是否是在过滤器规则内,这个规则定义在ClassPathScanningCandidateComponentProvider 类中我们之前分析过
	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        // bean在排除过滤器内返回false
		for (TypeFilter tf : this.excludeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
				return false;
			}
		}
        // bean在包含过滤器内,@component注解标注的bean
		for (TypeFilter tf : this.includeFilters) {
			if (tf.match(metadataReader, getMetadataReaderFactory())) {
                // @Conditional注解相关处理
				return isConditionMatch(metadataReader);
			}
		}
		return false;
	}

继续看 tf.match(metadataReader, getMetadataReaderFactory()) 匹配规则,这边省略父类规则,和接口匹配规则具体的代码,读者有兴趣自行研究;

public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
			throws IOException {

		// 元注解匹配规则
		if (matchSelf(metadataReader)) {
			return true;
		}
		ClassMetadata metadata = metadataReader.getClassMetadata();//获取元数据
		if (matchClassName(metadata.getClassName())) {// class是否匹配
			return true;
		}
		// 父类匹配规则
		if (this.considerInherited) {
			// .........
		}
		// 接口匹配规则
		if (this.considerInterfaces) {
			// .........
		}

		return false;
	}

我们重点关注的是元注解的匹配规则 matchSelf(metadataReader)方法;

	protected boolean matchSelf(MetadataReader metadataReader) {
        // 获取元注解
		AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
		// 判定 元注解中是否包含 @component注解
        return metadata.hasAnnotation(this.annotationType.getName()) ||
				(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
	}

到这边我们看看元注解都包括什么内容,其实就是我们的配置类;

我们也看见了this.annotationType.getName() 就是 @Componet 注解;我们最后进入 metadata.hasAnnotation(this.annotationType.getName())方法再深入跟踪到了 isPresent(Object requiredType, boolean directOnly) 方法 发现这边需要 @Componet ; 而我们 配置上写的是

@Configuration 和 @ComponentScan 注解并不满足条件(虽然@Configuration 中内部有@Componet);如果是**@Componet**我们这边已经通过了;

private boolean isPresent(Object requiredType, boolean directOnly) {
    	// 遍历元注解
		for (MergedAnnotation<?> annotation : this.annotations) {
            //获取元注解类型
			Class<? extends Annotation> type = annotation.getType();
            // 判定 元注解类型是否等于 必须的类型(comPonent)
			if (type == requiredType || type.getName().equals(requiredType)) {
				return true;
			}
		}
		if (!directOnly) {
			for (AnnotationTypeMappings mappings : this.mappings) {
				for (int i = 1; i < mappings.size(); i++) {
					AnnotationTypeMapping mapping = mappings.get(i);
					if (isMappingForType(mapping, requiredType)) {
						return true;
					}
				}
			}
		}
		return false;
	}

换另一个或条件 进入metadata.hasMetaAnnotation(this.annotationType.getName());

// metaAnnotationName = org.springframework.stereotype.Component
default boolean hasMetaAnnotation(String metaAnnotationName) {
		return getAnnotations().get(metaAnnotationName,
				MergedAnnotation::isMetaPresent).isPresent();
	}

这边一个isPresent() 方法进行判定 get 方法的结果是否存在,若存在返回true, 否则false; 所以最后我们看的还是 get 方法内部的实现

	@Override
	public <A extends Annotation> MergedAnnotation<A> get(String annotationType,
			@Nullable Predicate<? super MergedAnnotation<A>> predicate) {

		return get(annotationType, predicate, null);
	}

继续跟踪 MergedAnnotation 方法 是否返回有数据;

@Override
	public <A extends Annotation> MergedAnnotation<A> get(String annotationType,
			@Nullable Predicate<? super MergedAnnotation<A>> predicate,
			@Nullable MergedAnnotationSelector<A> selector) {

		MergedAnnotation<A> result = find(annotationType, predicate, selector);
		return (result != null ? result : MergedAnnotation.missing());
	}

经过层层嵌套的查找锁定 find(annotationType, predicate, selector);在这边会循环遍历配置类拥有的注解与给定的注解进行比对,如果成功通过select 选择器返回result;

private <A extends Annotation> MergedAnnotation<A> find(Object requiredType,
			@Nullable Predicate<? super MergedAnnotation<A>> predicate,
			@Nullable MergedAnnotationSelector<A> selector) {

		if (selector == null) {
			selector = MergedAnnotationSelectors.nearest();
		}

		MergedAnnotation<A> result = null;
		for (int i = 0; i < this.annotations.length; i++) {
			MergedAnnotation<?> root = this.annotations[i];
            // mappings 里面就是配置类拥有的注解
			AnnotationTypeMappings mappings = this.mappings[i];
			for (int mappingIndex = 0; mappingIndex < mappings.size(); mappingIndex++) {
				AnnotationTypeMapping mapping = mappings.get(mappingIndex);
                // 遍历判定mappings 中是否包含必须类型
				if (!isMappingForType(mapping, requiredType)) {
					continue;
				}// candidate 就是我们的配置类
				MergedAnnotation<A> candidate = (mappingIndex == 0 ? (MergedAnnotation<A>) root :
						TypeMappedAnnotation.createIfPossible(mapping, root, IntrospectionFailureLogger.INFO));
				if (candidate != null && (predicate == null || predicate.test(candidate))) {
					if (selector.isBestCandidate(candidate)) {
						return candidate;
					}
                    // 返回结果
					result = (result != null ? selector.select(result, candidate) : candidate);
				}
			}
		}
		return result;
	}

我们最后看下遍历的结果result;

回顾一下整个扫描基本包方式spring容器的初始化流程

2.5 BeaFactory和它的孩子们

经过上面的源码分析我们已经知道了spring容器的整个初始化过程,但我们肯定还是对每个容器的功能并不是很懂,所以还是需要分析一下重要的spring容器上下文;

容器始祖 BeaFactory

BeaFactory 的作用就是 获取bean, 判定单例原型,获取bean的提供者等提供一系列的规范;

public interface BeanFactory {

	// beanFactory的前缀 用于取消引用和区分bean,返回的是factory;
	String FACTORY_BEAN_PREFIX = "&";


	// 获取 bean
	Object getBean(String name) throws BeansException;

	// 获取 bean
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;
	// 获取 bean
	Object getBean(String name, Object... args) throws BeansException;

	// 获取 bean
	<T> T getBean(Class<T> requiredType) throws BeansException;

	// 获取 bean
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	// 获取 bean 的 provider
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	// 获取 bean 的 provider
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	// 是否包含 bean
	boolean containsBean(String name);

	// 是否单例
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	// 是否原型
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	 // 类型是否匹配
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	// 类型是否匹配
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;


	@Nullable// 获取类型
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;


	@Nullable// 获取类型
	Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

	// 获取别名
	String[] getAliases(String name);

}

二代始祖 HierarchicalBeanFactory

HierarchicalBeanFactory 的主要功能就是 支持获取 父类 的 BeanFactory;

public interface HierarchicalBeanFactory extends BeanFactory {

   // 获取 父 BeanFactory
   @Nullable
   BeanFactory getParentBeanFactory();

   // 是否包含 local bean factory 
   boolean containsLocalBean(String name);

}

二代始祖 ListableBeanFactory

ListableBeanFactory 对 BeanFactory 功能做了扩展,能够返回更多bean的信息;

public interface ListableBeanFactory extends BeanFactory {

	// bean factory 中是否包含 bean definition
	boolean containsBeanDefinition(String beanName);

	// 返回  bean factory 中 beans defined  的数量
	int getBeanDefinitionCount();

	 // 返回  bean factory 中 所有 beans defined  的名称
	String[] getBeanDefinitionNames();

	// 通过给定的类型返沪适配的 bean 的名称
	String[] getBeanNamesForType(ResolvableType type); 

	// 通过给定的类型(包括子类)返沪适配的 bean 的名称,
	String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);

	// 通过给定的类型(包括子类)返沪适配的 bean 的名称
	String[] getBeanNamesForType(@Nullable Class<?> type);

	// 通过给定的类型(包括子类)返沪适配的 bean 的名称;
	String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);

	// 通过类型返回 bean 的名称和实例
	<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;

	// 通过类型返回 bean 的名称和实例
	<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
			throws BeansException;

	// 返回所有的bean 名称 通过 注解类型
	String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);

	// 通过注解类型返回所有 bean 的名称 和实例
	Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;

	// 从指定的bean中返回 指定类型的注解 
	@Nullable 
	<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
			throws NoSuchBeanDefinitionException;

}

容器的提供者ApplicationContext

ApplicationContext 应用上下文作为中央接口,为应用程序提供配置,起着承上启下的作用;

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

	// 返回上下文id
	@Nullable
	String getId();

	// 返回部署的应用程序的名称,或者默认为空字符串
	String getApplicationName();

	// 返回上下文的显示名称
	String getDisplayName();

	// 返回上下文第一次加载的时间戳
	long getStartupDate();

	// 返回父上下文
	@Nullable
	ApplicationContext getParent();

	// 获取 AutowireCapableBeanFactory
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

资源配置ConfigurableApplicationContext

ConfigurableApplicationContext 实现了 ApplicationContext , 添加了资源加载配置功能, 比如环境变量的定义,加载class path 路径下的资源, jvm关闭后容器的摧毁都在这个上下文中定义;

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {

	//应用上下文配置时,这些符号用于分割多个配置路径
	String CONFIG_LOCATION_DELIMITERS = ",; \t\n";

	//BeanFactory中,ConversionService类所对应的bean的名字,如果未提供使用默认规则
	String CONVERSION_SERVICE_BEAN_NAME = "conversionService";

	// LoadTimeWeaver bean 在  factory 中的名字
	String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";

	//Environment bean 在factory中的名字
	String ENVIRONMENT_BEAN_NAME = "environment";

	// 系统属性 bean 在factory中的名字
	String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";

	// 系统环境 bean 在 factory 中的名字
	String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";

	// 启动步骤在factory中的名字
	String APPLICATION_STARTUP_BEAN_NAME = "applicationStartup";

	// 上下文关闭钩子名称
	String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";


	// 设置上下文id
	void setId(String id);

	// 设置父上下文
	void setParent(@Nullable ApplicationContext parent);

	// 为上下文设置环境
	void setEnvironment(ConfigurableEnvironment environment);

	// 返回上下文的环境
	@Override
	ConfigurableEnvironment getEnvironment();

	// 为上下文设置启动步骤
	void setApplicationStartup(ApplicationStartup applicationStartup);

	// 获取上下文启动步骤
	ApplicationStartup getApplicationStartup();

	// 添加后处理器,在reresh的时候调用
	void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);

	// 添加新的应用监听器,会唤起容器事件
	void addApplicationListener(ApplicationListener<?> listener);
	// 指定类加载器加载 class path 下的资源和 bean
	void setClassLoader(ClassLoader classLoader);

	// 为上下文注册protocol resolver
	void addProtocolResolver(ProtocolResolver resolver);

	// 加载资源配置,比如 基于java的基本配置,xml配置,属性文件等
	void refresh() throws BeansException, IllegalStateException;

	// 向 jvm 注入 钩子,当jvm关闭时,摧毁上下文;
	void registerShutdownHook();

	// 关闭应用上下文
	@Override
	void close();

	// 判定上下文是否激活
	boolean isActive();

	// 返回 bean factory
	ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

}

容器BeanDefinitionRegistry

BeanDefinitionRegistry 是一个注册表,里面注册了 BeanDefinition;AnnotationConfigApplicationContext(spring容器) 就是 BeanDefinitionRegistry 的子类;BeanDefinition 是 描述bean实例的信息;

//BeanDefinitionRegistry(bean的注册表含有definitions)
public interface BeanDefinitionRegistry extends AliasRegistry {

	//向注册表(Register)中注册新的definition
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	//从BeanDefinition中移除bean
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	//返回给定bean的BeanDefinition
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	
	//判定registry中是否含有给定的bean
	boolean containsBeanDefinition(String beanName);
	
	// 返回registry中bean的名称
	String[] getBeanDefinitionNames();
	
	//返回registry中bean的数量
	int getBeanDefinitionCount();
	
	//判定bean的名称是否已经被使用
	boolean isBeanNameInUse(String beanName);

}

BeanDefinition

BeanDefinition 包含 bean 的实例信息,比如bean的作用域,初始化方法,构造参数,摧毁方法,懒加载,工厂方法等等;

// BeanDefinition 包含bean实例的信息
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	//单例
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
	//原型
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

	//角色-用户自己定义的bean
	int ROLE_APPLICATION = 0;

	//角色-配置类较大的bean
	int ROLE_SUPPORT = 1;

	// 角色-内部工作使用的bean
	int ROLE_INFRASTRUCTURE = 2;


	// Modifiable attributes

	// 设置父的definition名称
	void setParentName(@Nullable String parentName);

	//获取父bean definition 名称
	@Nullable
	String getParentName();

	// 设置指定的 bean definition 名称
	void setBeanClassName(@Nullable String beanClassName);

	//获取  bean definition 名称
	@Nullable
	String getBeanClassName();

	// 设置作用域
	void setScope(@Nullable String scope);

	// 获取作用域
	@Nullable
	String getScope();

	// 设置bean 是否懒加载
	void setLazyInit(boolean lazyInit);

	// 判定bean 是否懒加载
	boolean isLazyInit();

	// 设置 bean 的依赖
	void setDependsOn(@Nullable String... dependsOn);

	// 获取bean依赖的bean名称
	@Nullable
	String[] getDependsOn();

	// 设置自动注入候选
	void setAutowireCandidate(boolean autowireCandidate);

	// 判定自动注入候选
	boolean isAutowireCandidate();

	// 设置 首要的bean
	void setPrimary(boolean primary);

	// 判定是否是首要的bean
	boolean isPrimary();

	// 指定bean 工厂 
	void setFactoryBeanName(@Nullable String factoryBeanName);

	// 返回 bean 工厂名称
	@Nullable
	String getFactoryBeanName();

	// 设定工厂方法
	void setFactoryMethodName(@Nullable String factoryMethodName);

	// 返回工厂方法
	@Nullable
	String getFactoryMethodName();

	// 返回bean 的构造器参数
	ConstructorArgumentValues getConstructorArgumentValues();

	// 判定构造器参数是否为空
	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}
	
	// 返回应用于实例中bean的属性值
	MutablePropertyValues getPropertyValues();

	// 判定bean中定义的属性值
	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

	// 设置初始化方法
	void setInitMethodName(@Nullable String initMethodName);

	// 返回初始化方法
	@Nullable
	String getInitMethodName();

	// 设置摧毁方法
	void setDestroyMethodName(@Nullable String destroyMethodName);

	// 获取摧毁的方法
	@Nullable
	String getDestroyMethodName();

	// 设置角色
	void setRole(int role);

	// 获取角色
	int getRole();

	// 设置bean definition 的描述
	void setDescription(@Nullable String description);

	// 返回bean  definition 的描述
	@Nullable
	String getDescription();

	// Read-only attributes
	// 返回bean 的解析类型
	ResolvableType getResolvableType();

	/判定bean是否 单例
	boolean isSingleton();/

	// 判定bean是否 原型
	boolean isPrototype();
	// 判定bean是否抽象
	boolean isAbstract();
	// 返回bean资源的描述
	@Nullable
	String getResourceDescription();
	// 返回原始bean的 BeanDefinition
	@Nullable
	BeanDefinition getOriginatingBeanDefinition();

}

再看UML图AbstractBeanDefinition 是 继承了 BeanDefinition;

现在是不是有一种感觉BeanDefinitionRegistry 就是一个容器,里面注入了大量的bean的信息BeanDefinition

2.6 附步骤

步骤属于 spring-core 包,是用于记录spring容器的运行步骤;

public interface ApplicationStartup {// spring容器启动后标记步骤

	ApplicationStartup DEFAULT = new DefaultApplicationStartup();

	StartupStep start(String name);//开始执行的步骤

}

ApplicationStartup 的实现类是DefaultApplicationStartup;

class DefaultApplicationStartup implements ApplicationStartup {

	@Override
	public DefaultStartupStep start(String name) {
		return new DefaultStartupStep();
	}

	static class DefaultStartupStep implements StartupStep {
		// 初始的记录为false
		boolean recorded = false;
		// 默认标签
		private final DefaultTags TAGS = new DefaultTags();
		@Override
		public String getName() {
			return "default";
		}
		// 获取当前步骤id
		@Override
		public long getId() {
			return 0L;
		}
		// 获取父步骤id
		@Override
		public Long getParentId() {
			return null;
		}
		// 获取标签
		@Override
		public Tags tags() {
			return this.TAGS;
		@Override
		public StartupStep tag(String key, String value) {
			if (this.recorded) {
				throw new IllegalArgumentException();
			}
			return this;
		}
		@Override
		public StartupStep tag(String key, Supplier<String> value) {
			if (this.recorded) {
				throw new IllegalArgumentException();
			}
			return this;
		}
		// 结束后记录为true
		@Override
		public void end() {
			this.recorded = true;
		}

		// 标签是本质一个迭代器用于存放 StartupStep.Tag具体可以看接口StartupStep
		static class DefaultTags implements StartupStep.Tags {

			@Override
			public Iterator<StartupStep.Tag> iterator() {
				return Collections.emptyIterator();
			}
		}
	}

}

DefaultApplicationStartup 内部有个静态类DefaultStartupStep实现 StartupStep接口,定义了具体步骤的规范

public interface StartupStep {
	// 返回步骤名称
	String getName();
	// 唯一的步骤id
	long getId();
	// 父步骤id
	@Nullable
	Long getParentId();
	// 对步骤添加标签
	StartupStep tag(String key, String value);
	// 对步骤添加标签
	StartupStep tag(String key, Supplier<String> value);
	// 返回步骤的标签集合
	Tags tags();
	// 记录的是步骤的状态 
	void end();
	// 可变集合
	interface Tags extends Iterable<Tag> {
	}
	//key和value 关联 步骤的元数据
	interface Tag {
		// 返回表情 名称 即key
		String getKey();
		// 返回 value
		String getValue();
	}
}

实现类如下:

相关文章