AnnotationConfigApplicationContext继承了GenericApplicationContext,GenericApplicationContext里有个很重要的实例-- DefaultListableBeanFactory 。 DefaultListableBeanFactory 是spring中,默认注册、加载的实现。
sacn和register方法,是把扫描或者指定的配置bean信息,注册到容器中。
register方法是通过注解bean读取器AnnotatedBeanDefinitionReader来实现的。
public void register(Class<?>... annotatedClasses) { Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified"); this.reader.register(annotatedClasses); }
AnnotatedBeanDefinitionReader的方法
按指定的配置bean注册信息
public void register(Class<?>... annotatedClasses) { for (Class<?> annotatedClass : annotatedClasses) { registerBean(annotatedClass); } }
public void registerBean(Class<?> annotatedClass) { doRegisterBean(annotatedClass, null, null, null); }
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { // 其实就是创建BeanDefinition了,只是多了一个注解的属性metadata AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); // @Conditional注解的判断在这里,如果不符合条件,就不注册了 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } // 回调用的 abd.setInstanceSupplier(instanceSupplier); // 解析bean的作用域,scope,没有设置默认单例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); // 解析bean的名称 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); // 设置abd的Lazy, primary DependsOn, Role ,Description这五个属性 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,就是beanName和BeanDefinition的映射 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); // 是否有代理 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 往容器注册 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
scan方法是通过按类路径扫描注解bean的扫描器ClassPathBeanDefinitionScanner来实现的。
public void scan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); this.scanner.scan(basePackages); }
ClassPathBeanDefinitionScanner的方法。
根据指定目录扫描,返回注册的bean的个数
public int scan(String... basePackages) { // 获取没扫描前bean的个数 int beanCountAtScanStart = this.registry.getBeanDefinitionCount(); // 主要方法 doScan(basePackages); // Register annotation config processors, if necessary. if (this.includeAnnotationConfig) { AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } // 当前bean的个数 - 没扫描前bean的个数 = 本次扫描时注册的bean的个数 return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart); }
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) { // 根据路径扫描,获取BeanDefinition,这个BeanDefinition是ScannedGenericBeanDefinition。默认Component、ManagedBean、Named注解会被扫描进来,其中ManagedBean是JSR-250规范,Named是JSR-330规范,都需要额度的jar包支持。 // register的conditionEvaluator判断@Conditional注解也是在这里判断。 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { // 解析bean的作用域,scope,没有设置默认单例 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); // 解析bean的名称 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); // 设置默认的属性,比如lazy属性是false,还有autowireMode、dependencyCheck、initMethodName、destroyMethodName、enforceInitMethod、enforceDestroyMethod这几个属性设置 if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } // 如果是注解的话,设置abd的Lazy, primary DependsOn, Role ,Description这五个属性 if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 检查beanName如果没注册过,返回false。如果注册过了,要看是否兼容,如果不兼容,抛异常,如果兼容,这边不在注册。 if (checkCandidate(beanName, candidate)) { // 定义一个BeanDefinitionHolder,就是beanName和BeanDefinition的映射 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // 是否有代理 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 加入到beanDefinitions beanDefinitions.add(definitionHolder); // 注册bean registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }