还是之前的小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
其实就是存储字节码信息
总结
BeanFactory: 存储了spring创建的bean实例以及Bean的信息
Metadata: 存储了class字节码信息
BeanDefinition:不但存储了上面的metadata还存储bean的注解的信息等等
到此我们大致清楚了sprinng的大概流程:
- 扫描
- 将扫描的包信息解析成BeanDefinition对象
- 读取BeanDefinition中的数据实例化
当然还有好多细节我们还没有看,比如@Autowired, @Value这些注解的对象是什么时候注入进去的? 怎么处理依赖的先后关系的?