2, 注解spring-Bean加载流程

还是之前的小demo, 上一篇文章我们通过debug了解了spring包的扫描, 今天我们接着看spring是如何加载这些Bean的。

demo

String pacakge = SpringTest02.class.getPackage().getName();
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(pacakge);
Object bean = annotationConfigApplicationContext.getBean("testBean02");
System.out.println(bean.getClass());

源码跟踪

--1, SpringTest02.java-->
new AnnotationConfigApplicationContext(pacakge);


--2, AnnotationConfigApplicationContext.java-->
public AnnotationConfigApplicationContext(String... basePackages) {
	this();
	// 扫描(点进去)
	scan(basePackages);
	refresh();
}

--3, AnnotationConfigApplicationContext.java-->
public void scan(String... basePackages) {
	this.scanner.scan(basePackages);
}

--4, ClassPathBeanDefinitionScanner.java-->
public int scan(String... basePackages) {
	doScan(basePackages);
	...
}

--5, ClassPathBeanDefinitionScanner.java-->
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
	for (String basePackage : basePackages) {
	    // 这边已经返回了加载好的BeanDefinition(点进去)
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		for (BeanDefinition candidate : candidates) {
		   ...
		}
	}
	return beanDefinitions;
}

--6, ClassPathScanningCandidateComponentProvider.java-->
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
	if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
		return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
	}
	else {
	    // (点进去)
		return scanCandidateComponents(basePackage);
	}
}

--7, ClassPathScanningCandidateComponentProvider.java-->
// 代码经过省略, 去掉了一些不必要的判断, 异常捕获, 日志输出
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
	Set<BeanDefinition> candidates = new LinkedHashSet<>();
	try {
	    // 上个教程的包扫描内容
		String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
				resolveBasePackage(basePackage) + '/' + this.resourcePattern;
		Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
		boolean traceEnabled = logger.isTraceEnabled();
		boolean debugEnabled = logger.isDebugEnabled();
		for (Resource resource : resources) {
		    // metadataReader 源码见下面分析
			MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
			if (isCandidateComponent(metadataReader)) {
			    // 这边创建了BeanDefinition
				ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
				sbd.setSource(resource);
				// 判断是否使用了@Component注解
				if (isCandidateComponent(sbd)) {
					candidates.add(sbd);
				}
			}
		}
	}
	return candidates;
}

到现在我们发现了spring是怎么将class字节码解析成BeanDefinition对象的, 具体解析后面再讲, 现在我们接着看spring是如何处理这些BeanDefinition?

上面加载完,方法结束, 我们回到doScan接着看源码(就是上面的第5)
--1, ClassPathBeanDefinitionScanner.java-->
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
	for (String basePackage : basePackages) {
	    // 这边已经返回了加载好的BeanDefinition(点进去)
		Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
		for (BeanDefinition candidate : candidates) {
		    ....
		}
	}
	return beanDefinitions;
}

// 方法结束, 返回上一步
--2, AnnotationConfigApplicationContext.java-->
public AnnotationConfigApplicationContext(String... basePackages) {
	this();
	scan(basePackages);
	// (点进去)
	refresh();
}

--3, AnnotationConfigApplicationContext.java-->
@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// 创建了BeanFactory, 创建了DefaultListableBeanFactory对象
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			...
			// 创建bean实例(点开)
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		}

		catch (BeansException ex) {
			...
		}
	}
}


--4, AbstractApplicationContext.java-->
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    ...
	// Instantiate all remaining (non-lazy-init) singletons.(点开)
	beanFactory.preInstantiateSingletons();
}


--5, DefaultListableBeanFactory.java-->
@Override
public void preInstantiateSingletons() throws BeansException {

	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
	    // 打断点, 一直到加载到自己的bean
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
			    // 我们自己的bean不是工厂bean, 直接忽略
				...
			}
			else {
			    // 点开
				getBean(beanName);
			}
		}
	}

	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

--6, AbstractBeanFactory.java-->
@Override
public Object getBean(String name) throws BeansException {
    // 真正干活生成bean的
	return doGetBean(name, null, null, false);
}

--7, AbstractBeanFactory.java-->
protected <T> T doGetBean(
	String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly){
    ...
	// Create bean instance.
	if (mbd.isSingleton()) {
	    // lambda表达式, 常见一个匿名对象ObjectFactory, 有下面调用里面的getObject()方法(点进去)
		sharedInstance = getSingleton(beanName, () -> {
			try {
				return createBean(beanName, mbd, args);
			}
			catch (BeansException ex) {
    			...
			}
		});
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
	}
	...
	return (T) bean;
}

--8, DefaultSingletonBeanRegistry.java-->
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        // getObject()就是调用上面的7中的return createBean(...)
		singletonObject = singletonFactory.getObject();
		return singletonObject;
	}
}


--9, AbstractAutowireCapableBeanFactory.java-->
// 直接回到7中的createBean(), 然后点进去
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {
    // 发现了do, (点进去)
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	return beanInstance;

}


--10, AbstractAutowireCapableBeanFactory.java-->
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
	...
	// (点进去)
	return instantiateBean(beanName, mbd);
}

--11, AbstractAutowireCapableBeanFactory.java-->
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
	try {
		Object beanInstance;
		if (System.getSecurityManager() != null) {
    		...
		}
		else {
		    // getInstantiationStrategy()判断是用cglib代理还是jdk动态代理(本文beanTest02没有接口, 因此是用的cglib代理), instantiate方法点进去
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}


--12, SimpleInstantiationStrategy.java-->
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
	Constructor<?> constructorToUse;
	// 这边是判断是否需要使用cglib代理来生成代理类
	if (!bd.hasMethodOverrides()) {
		....
		// 获取构造方法
		constructorToUse = clazz.getDeclaredConstructor();
		...
		// BeanUtils来创建实例
		return BeanUtils.instantiateClass(constructorToUse);
	}else {
		// Must generate CGLIB subclass.
		return instantiateWithMethodInjection(bd, beanName, owner);
	}
}

上面只是跟踪了spring生成single的bean对象, 那么非single对象是怎么生成的?

我们添加一个类TestBean03.java

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TestBean03 {
}

debug之后, 我们发现在beanFactory初始化完成之后, 都没有创建TestBean03, 因为是多例的, 我们还以是在获取的时候去创建了。

--1, SpringTest02.java-->
// 点进去
Object bean1 = annotationConfigApplicationContext.getBean("testBean03");
System.out.println(bean1.getClass());


--2, AbstractApplicationContext.java-->
@Override
public Object getBean(String name) throws BeansException {
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name);
}

--3, AbstractApplicationContext.java-->
@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

--4, -->
protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
        // 单利, 上面的流程
		if (mbd.isSingleton()) {
			...
		}
        // 多例
		else if (mbd.isPrototype()) {
			// It's a prototype -> create a new instance.
			Object prototypeInstance = null;
			try {
				beforePrototypeCreation(beanName);
				prototypeInstance = createBean(beanName, mbd, args);
			}
			finally {
				afterPrototypeCreation(beanName);
			}
			bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
		}
}

现在我们知道了单利的对象spring BeanFactory初始化完成后,会创建对象并保存到beanFactory中, 对于多例的会在需要的时候在创建。

MetadataReader

MetadataReader其实就是保存了class资源以及AnnoationMetadata

final class SimpleMetadataReader implements MetadataReader {

	private final Resource resource;

	private final AnnotationMetadata annotationMetadata;
}

AnnoationMetadata

其实就是存储字节码信息

10937D5654F646678245F36AC75E5835.jpg

总结

BeanFactory: 存储了spring创建的bean实例以及Bean的信息

Metadata: 存储了class字节码信息

BeanDefinition:不但存储了上面的metadata还存储bean的注解的信息等等

到此我们大致清楚了sprinng的大概流程:

  1. 扫描
  2. 将扫描的包信息解析成BeanDefinition对象
  3. 读取BeanDefinition中的数据实例化

当然还有好多细节我们还没有看,比如@Autowired, @Value这些注解的对象是什么时候注入进去的? 怎么处理依赖的先后关系的?