SpringIoC容器加载流程
代码如下
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
整体调用链如下
进入构造方法
public AnnotationConfigApplicationContext(Class>... annotatedClasses) { this(); register(annotatedClasses); refresh(); }
- 先看看调用无参构造this()后,Spring都做了哪些事呢
整体构造调用链可以简化为以下
可以看到AnnotationConfigApplication最顶级的父类即是DefaultResourceLoader,我们知道面向对象编程中,继承关系中构造方法从父类依次向子类执行。所以现在看下在这过程中Spirng都帮我们做了哪些事情
源码如下:
- DefaultResourceLoader.class
public DefaultResourceLoader() { this.classLoader = ClassUtils.getDefaultClassLoader(); }
首先是获取默认的类加载器
获取流程是什么样的呢,点到spring提供的工具类里面去,看下这段代码
@Nullable public static ClassLoader getDefaultClassLoader() { ClassLoader cl = null; try { cl = Thread.currentThread().getContextClassLoader();//获取当前线程的类加载器 } catch (Throwable var3) { } if (cl == null) { cl = ClassUtils.class.getClassLoader();//获取当前类的类加载器 if (cl == null) { try { cl = ClassLoader.getSystemClassLoader();//获取系统类加载器 } catch (Throwable var2) { } } } return cl; }
这里逻辑相对简单,首先去获取当前线程的类加载器,如果获取不到就去获取当前类的类加载器,如果也获取不到,就去获取系统的类加载器。
至此,classLoader就由此构造方法先给到了一个类加载器,此时断点调出当前类,到抽象类看看做了什么。
- AbstractApplicationContext.class
public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver(); }
这个抽象类主要是,构造出
private ResourcePatternResolver resourcePatternResolver;
这里有点绕,再看看当前类的类图
由于此抽象类实现的接口中有一层就是ResourcePatternResolver这个接口,可以看到此抽象类中对该方法的实现
@Override public Resource[] getResources(String locationPattern) throws IOException { return this.resourcePatternResolver.getResources(locationPattern); }
那这个Resource又是个啥?有啥作用呢?
把代码跟过来看一下
public interface ResourcePatternResolver extends ResourceLoader { String CLASSPATH_ALL_URL_PREFIX = "classpath*:"; Resource[] getResources(String var1) throws IOException; } public interface ResourceLoader { String CLASSPATH_URL_PREFIX = "classpath:"; Resource getResource(String var1); @Nullable ClassLoader getClassLoader(); }
public interface Resource extends InputStreamSource{ //xxx } public interface InputStreamSource { InputStream getInputStream() throws IOException; }
点过来可以看到,原来这个ResourceLoader是Spring框架对资源访问的一个对象。其底层就是一个InputStream输入流的对象,只不过Spring对他进行了一次封装。
到这里,就比较清晰了,其实这两个抽象类做的事情
- 设置默认类加载器,2.构造出Spring访问静态资源的Resource对象
- GenericApplicationContext.class
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
这里点过去看看,创建出DefaultListableBeanFactory
public DefaultListableBeanFactory() { }
这里是个空方法,其实也就是创建出一个DefaultListableBeanFactory 的bean工厂的对象。
- AnnotationConfigApplicationContext.class
public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
最后回到这个方法,里面做了两件事,构造this.reader和this.scanner,那这两个又是啥东西,能干嘛呢?
点进去这两个源码
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); } public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { registerDefaultFilters(); } setEnvironment(environment); setResourceLoader(resourceLoader); }
所以可以看到
this.reader为注解的方式,读到IoC容器
this.scanner为扫包的形式,读到IoC容器
到这里,基本对构造this()构造方法执行有点概念了
接下来就是IoC容器加载的核心
register(annotatedClasses);的部分
这里点进去
public void register(Class>... annotatedClasses) { Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); this.reader.register(annotatedClasses); }
首先看到了调用到了this.reader这个对象,由于我们用的是基于注解的方式,所以刚刚的this.reader方法的初始化也得到了论证。
继续往下点
public void register(Class>... annotatedClasses) { for (Class> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } } public void registerBean(Class> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); }
这里由于入参类型是数组,所以存在传入多个类,因此,这里是循环去注册Bean,到Ioc容器中。那就看看注册的动作是啥样的
void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name, @Nullable Class extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); if (this.conditionevaluator.shouldSkip(abd.getmetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd); abd.setScope(scopemetadata.getScopeName()); String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); if (qualifiers != null) { for (Class extends Annotation> qualifier : qualifiers) { if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
到这里,就是到了IoC容器的核心代码了
从上往下依次是
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
这个里面两个动作
this.setBeanClass(beanClass); this.metadata = new StandardAnnotationmetadata(beanClass, true);
作用就是将注解的相关信息,设置到我们的AnnotatedGenericBeanDefinition对象里面
if (this.conditionevaluator.shouldSkip(abd.getmetadata())) { return; }
这个是判断是否有条件注入,如果有判断到这个注解,就不将其注入到IoC容器中
abd.setInstanceSupplier(instanceSupplier);
这个的作用为:设置回调
Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd); abd.setScope(scopemetadata.getScopeName());
这里判断你是否加了@Scope这个注解,默认情况下为单例
可以点进去看看源码
@Override public Scopemetadata resolveScopemetadata(BeanDefinition definition) { Scopemetadata metadata = new Scopemetadata(); if (definition instanceof AnnotatedBeanDefinition) { AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( annDef.getmetadata(), this.scopeAnnotationType); if (attributes != null) { metadata.setScopeName(attributes.getString("value")); ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = this.defaultProxyMode; } metadata.setScopedProxyMode(proxyMode); } } return metadata; }
接下来
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { if (definition instanceof AnnotatedBeanDefinition) { String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); if (StringUtils.hasText(beanName)) { // Explicit bean name found. return beanName; } } // Fallback: generate a unique default bean name. return buildDefaultBeanName(definition, registry); } @Nullable protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) { Annotationmetadata amd = annotatedDef.getmetadata(); Settypes = amd.getAnnotationTypes(); String beanName = null; for (String type : types) { AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); if (attributes != null && isStereotypeWithNamevalue(type, amd.getmetaAnnotationTypes(type), attributes)) { Object value = attributes.get("value"); if (value instanceof String) { String strVal = (String) value; if (StringUtils.hasLength(strVal)) { if (beanName != null && !strVal.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " + "component names: '" + beanName + "' versus '" + strVal + "'"); } beanName = strVal; } } } } return beanName; }
这里,首先判断你是否是注解的方式注入,判断是否有传beanName,如果没有就给一个默认的beanName,默认首字母小写的类名。
具体的为:determineBeanNameFromAnnotation()方法就是看一下你有没有自己设置bean的名称
如果没有,就走buildDefaultBeanName(definition, registry);这个方法给你设置一个默认的bean名称。
接下来
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { processCommonDefinitionAnnotations(abd, abd.getmetadata()); } static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypemetadata metadata) { AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } else if (abd.getmetadata() != metadata) { lazy = attributesFor(abd.getmetadata(), Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } } if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null) { abd.setDependsOn(dependsOn.getStringArray("value")); } if (abd instanceof AbstractBeanDefinition) { AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd; AnnotationAttributes role = attributesFor(metadata, Role.class); if (role != null) { absBd.setRole(role.getNumber("value").intValue()); } AnnotationAttributes description = attributesFor(metadata, Description.class); if (description != null) { absBd.setDescription(description.getString("value")); } } }
这里就是判断下你是否带上了@ Lazy、@ Primary、@ DependsOn、@ Role、@ Description这些注解,如果带上了,进行一些相应的处理。
@ DependsOn:加载优先级
@ Role:有没有设置分类
往下
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry);
这里为啥要用一个BeanDefinitionHolder呢,debug一下可以看到,BeanDefinitionHolder对象内部包括了
private final BeanDefinition beanDefinition; private final String beanName; @Nullable private final String[] aliases;
由于beanDefinition中不包含beanName,无法注入到IoC容器中,所以会需要用BeanDefinitionHolder再给他包装有带一个beanName的对象。
最后
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if (aliases != null) { String[] var4 = aliases; int var5 = aliases.length; for(int var6 = 0; var6 < var5; ++var6) { String alias = var4[var6]; registry.registerAlias(beanName, alias); } } }
这里就是注册到IoC容器的动作了,可以看到这里首先会去获取beanName,也就说明了,为什么前面会需要带beanName这个节点。
这里的registry.registerBeanDefinition(),一共具有三个实现类:DefaultListableBeanFactory、GenericApplicationContext、SimpleBeanDefinitionRegistry。那到底是哪个实现类呢,其实再初始化this()里面,初始化父类的时候有一段源码如下。
public GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
可以看到beanFactory类型为DefaultListableBeanFactory
此时子类中this.registry = 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; this.conditionevaluator = new Conditionevaluator(registry, environment, null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); }
因此
this.reader = new AnnotatedBeanDefinitionReader(this);
里面的
private final BeanDefinitionRegistry registry;
即是前面父类给过来的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 { ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9); } } BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (this.hasBeanCreationStarted()) { synchronized(this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); ListupdatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set updatedSingletons = new linkedHashSet(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }
那么其实最后是通过
this.beanDefinitionMap.put(beanName, beanDefinition);
进行注册到IoC容器中,至此注册一些基本的信息到SpringIoC容器已经完成
最后到this.refresh();方法,主要分析其bean的生命周期流程,见下图
源码如下
public void refresh() throws BeansException, IllegalStateException { synchronized(this.startupShutdownMonitor) { this.prepareRefresh(); ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory); this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } } }
bean的加载是从
// Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);
开始执行
进入这个方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
进入beanFactory.preInstantiateSingletons();这个方法,这个方法中主要看到getBean()方法,因为当bean不存在的时候,该方法即会进行创建。
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
进入doGetBean方法,看到createBean()方法
try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); }
继续跟到doCreateBean方法
核心在于
try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); }
这段代码中就执行了bean的生命周期的主要流程
其中populateBean()主要完成对bean属性的设置
其中initializeBean()方法里面,完成了BeanPostProcessor的主要内容
其中主要分析
invokeAwareMethods()方法
源码如下
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
这里首先会校验下是否属于Aware这个类
然后分别判断是否实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware这些接口,如果实现了,执行对应实现该接口的类中的具体代码
往回看,接着代码往下走
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
这个则是通过反射,执行到具体实现的前置通知方法
invokeInitMethods(beanName, wrappedBean, mbd);
这个就是执行init方法里面的内容了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这个就执行init方法完成后的后置通知方法了,类似aop的环绕
到这里spring-bean的生命周期就基本上结束了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)