/** * Create a new AnnotationConfigApplicationContext, scanning for components * in the given packages, registering bean definitions for those components, * and automatically refreshing the context. * @param basePackages the packages to scan for component classes */ publicAnnotationConfigApplicationContext(String... basePackages) { this(); scan(basePackages); refresh(); }
this () 方法
可以看到this方法,基本是在做一些对环境初始化的操作.
/** * Create a new AnnotationConfigApplicationContext that needs to be populated * through {@link #register} calls and then manually {@linkplain #refresh refreshed}. 同时还会走到 : org.springframework.context.support.GenericApplicationContext#GenericApplicationContext()这个方法里面来. this.beanFactory = new DefaultListableBeanFactory(); 可以看到这里是new了一个beanFactory的,也就是我们后面的refresh()方法,可以看到DefaultListableBeanFactroy这个类. 再往父类走 : org.springframework.context.support.AbstractApplicationContext#AbstractApplicationContext()就会走到这个类的这个方法来, this.resourcePatternResolver = getResourcePatternResolver(); 这里可以看到是初始化了 resourcePatternResolver.当然了,肯定还有一些new的全局变量的初始化也会进行初始化的. */ publicAnnotationConfigApplicationContext() { this.reader = newAnnotatedBeanDefinitionReader(this); //这个方法对registry,environment和resourceLoader进行赋值,然后根据filter是true,添加了三个filter过滤器.可以看到这个方法虽然带了scanner名字,但是看每个走的方法,好像是没有扫描任何东西,都是对全局参数进行赋值等操作. this.scanner = newClassPathBeanDefinitionScanner(this); }
---------------------------------
/** * Create a new {@code AnnotatedBeanDefinitionReader} for the given registry. * <p>If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext}, * the {@link Environment} will be inherited, otherwise a new * {@link StandardEnvironment} will be created and used. * @param registry the {@code BeanFactory} to load bean definitions into, * in the form of a {@code BeanDefinitionRegistry} * @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment) * @see #setEnvironment(Environment) 这里可以看到传入进来的registry是 this,也就是传入了AnnotationConfigApplicationContext它自己. 可以看到这个方法主要做的事情是,初始化Environment,然后new一个ConditionEvaluator对象,其保存了五个信息. 最后就分别添加五个 Processor到beanFactroy的beanDefinitionMap中来. */ publicAnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { // getOrCreateEnvironment()方法,先对registry进行非null的判断,如果是Null的话,就会抛出对应的异常.最后是new StandardEnvironment()了一个对象返回来. registry是满足EnvironmentCapable // this()方法:先对传入进来的registry和environemnt进行非null的判断.this.registry = registry; 紧着new了一个ConditionEvaluator对象,其构造函数中,初始化了registry,beanFactory,environment,resourceLoader和classLoader这五个参数,是在内部类ConditionContextImpl中. 最后往beanFactory的beanDefinitionMap中添加了五个值,分别是: //org.springframework.context.annotation.internalConfigurationAnnotationProcessor //org.springframework.context.annotation.internalAutowiredAnnotationProcessor //org.springframework.context.annotation.internalCommonAnnotationProcessor //org.springframework.context.event.internalEventListenerProcessor //org.springframework.context.event.internalEventListenerFactory //添加完,new AnnotatedBeanDefinitionReader()这个方法就走完了. this(registry, getOrCreateEnvironment(registry)); }
---------------------------------- /** * Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory. * @param registry the {@code BeanFactory} to load bean definitions into, in the form * of a {@code BeanDefinitionRegistry} */ publicClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) { this(registry, true); }
Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; // 这里传入的是ture,也就是会走到这个if里面来. if (useDefaultFilters) { //org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#registerDefaultFilters, 往includeFilters 集合中添加Filter,这些添加的filter,点进去看即可. registerDefaultFilters(); } // this.environment赋上传入进来的environment值. setEnvironment(environment); // org.springframework.core.io.support.ResourcePatternUtils#getResourcePatternResolver进行判断,这里由于是ResourcePatternResolver,所以在第一个if就返回了. //接着new一个CachingMetadataReaderFactory,传入进去resourceLoader,new这个类的内部也是可以看,就是对参数进行赋值,并没有做其他的什么事情了. //this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());获取出来的值Null. setResourceLoader(resourceLoader); }
scan(basePackages) 方法
// 对传入进来的参数进行一个校验. //scanner也是上面那步this.scanner = new ClassPathBeanDefinitionScanner(this)给new出来的. publicvoidscan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); this.scanner.scan(basePackages); }
/** * Perform a scan within the specified base packages. * @param basePackages the packages to check for annotated classes * @return number of beans registered */ publicintscan(String... basePackages) { // org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanDefinitionCount 走到这步来获取个数,还记得new AnnotatedBeanDefinitionReader(this)这个方法里面添加了五个processor吗?所以这里获取出来的beanCountAtScanStart大小就是5(默认对初始化做任何改动的情况下). intbeanCountAtScanStart=this.registry.getBeanDefinitionCount(); //从名字上看,这个方法是真正的做扫描的.其实Spring中,scan都算不做事的,doScan才是真的做事的。到后面还有getBean不是做事的,doGetBean才是做事的,createBean也是的. //doScan做的事情可以看到,读取包下的类,然后根据filter条件来过滤,满足条件的话,就会封装成ScannedGenericBeanDefinition,最后是一个集合包装的该包下全部满足条件的. 然后就是接着对 sbd进行注解的处理,比如有些打入了Lazy等注解的,都要读取出来,存入bd的信息中.最后再检查一遍db,如果没问题的话,就会根据beanName和bd,new一个BeanDefinitionHolder出来,最后注册到beanFactory中去,也就是放入BeanFactory的beanDeifitionMap中去. doScan(basePackages); // Register annotation config processors, if necessary. if (this.includeAnnotationConfig) { // 先获取出beanFactory,先调用beanFactory的getDependencyComparator和getAutowireCandidateResolver方法,如果满足条件的话,就会有对应的set方法.然后紧接着就是判断beanFactory中是否包含一些bd,如果是不包含的话,这里就会添加进去. 这里判断的值,再最初new reader()的时候已经有添加到BeanFactory的beanDifitionMap中去. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } // 这里返回int参数,但是 this.scanner.scan(basePackages); 好像并没有使用到返回值. return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart); }
/** * Perform a scan within the specified base packages, * returning the registered bean definitions. * <p>This method does <i>not</i> register an annotation config processor * but rather leaves this up to the caller. * @param basePackages the packages to check for annotated classes * @return set of beans registered if any for tooling registration purposes (never {@code null}) */ protected Set<BeanDefinitionHolder> doScan(String... basePackages) { // 先是对传入进来的参数进行检验. Assert.notEmpty(basePackages, "At least one base package must be specified"); // 存BeanDefinitionHolder的集合,也是最后要返回的. Set<BeanDefinitionHolder> beanDefinitions = newLinkedHashSet<>(); for (String basePackage : basePackages) { //根据传入进去的包名字,读取出包名字下的所有文件,然后迭代这些文件,这些文件要有能读的权限,再走isCandidateComponent(metadataReader)这个方法,其中就有使用 excludeFilters和includeFilters,这二个filter来过滤进行一些判断操作. 返回ture,就会往下走,new一个ScannedGenericBeanDefinition,其中beanClass就是这个类的全限定名字.比如这里(com.iyang.spring.bean.YangBeanOne),我们的是这个. //这就是这个方法,扫描,然后根据特定filter,如果是满足条件的话,就会new一个sbd,然后放入Set集合中,返回. Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //org.springframework.context.annotation.AnnotationScopeMetadataResolver#resolveScopeMetadata,走的这个方法,因AnnotationConfigUtils.attributesFor(...)方法返回的是null,所以这个里面就仅仅只是new了一个ScopeMetadata对象返回了 ScopeMetadatascopeMetadata=this.scopeMetadataResolver.resolveScopeMetadata(candidate); //scope的值是singletone.这不就是我们熟悉的单例嘛. candidate.setScope(scopeMetadata.getScopeName()); //获取出这个bean的名字 StringbeanName=this.beanNameGenerator.generateBeanName(candidate, this.registry); // db是 AbstractBeanDefinition的话,这里肯定是,从AbstractBeanDefinition这个名字上看,是一个抽象的,也就是应该是父类. if (candidate instanceof AbstractBeanDefinition) { //beanDefinition.applyDefaults(this.beanDefinitionDefaults)该方法是对一些参数进行赋值操作. // postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } // bd是AnnotatedBeanDefinition或者其子类. if (candidate instanceof AnnotatedBeanDefinition) { // 该方是对bd的Lazy.calss,Primary.class,DependsOn.class,Role.class,Description.class这些注解进行获取,如果有的话,就会调用bd对应的set方法给值set进去. 当然我们这里的bean没有这些属性.这里可自行加入一些注入,然后debug到这个地方进行看. AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 检查registry中是否含有这个beanName,如果没包含的话,就直接返回ture. if (checkCandidate(beanName, candidate)) { // 传入bean和beanName, new一个bean的Holder出来,也就是bean的持有者的意思.其实个人觉得这里是对bean进行一层封装,Holder更抽象地理解点. BeanDefinitionHolderdefinitionHolder=newBeanDefinitionHolder(candidate, beanName); //scopeMetadata中获取出getScopedProxyMode,如果是No的话,就直接返回definitionHolder definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 添加到最外层的集合中 beanDefinitions.add(definitionHolder); //org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition,最后走到了这里,该方法会先对传入进来的参数进行非null的判断,如果bd是AbstractBeanDefinition的话,就会强转调用其validate()方法,进行检验. 在从this.beanDefinitionMap中获取,根据beanName,第一次肯定是获取不到的,走到else.else中在判断hasBeanCreationStarted(),这里返回的是flase,也就是走到了else的else中去了,根据beanName和bean存入到this.beanDefinitionMap中,然后beanName添加到beanDefinitionNames集合中. 这就是这步根据beanName和bean放入beanFactory的beanDefinitionMap集合中. registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }