@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Configuration { /** * Explicitly specify the name of the Spring bean definition associated * with this Configuration class. If left unspecified (the common case), * a bean name will be automatically generated. *
The custom name applies only if the Configuration class is picked up via
? ? * component scanning or supplied directly to a {@link AnnotationConfigApplicationContext}.
? ? * If the Configuration class is registered as a traditional XML bean definition,
? ? * the name/id of the bean element will take precedence.
? ? * @return the suggested component name, if any (or empty String otherwise)
? ? * @see org.springframework.beans.factory.support.DefaultBeanNameGenerator
? ? */
? ? @AliasFor(annotation = Component.class)
? ? String value() default "";
}
1失都、AnnotatedBeanDefinitionReader
針對(duì)?main()方法所在的類進(jìn)行注解解析的是通過(guò)?BeanDefinitionLoader來(lái)操作的,而具體的解析操作其實(shí)是其內(nèi)部的屬性?annotatedReader來(lái)實(shí)現(xiàn)的
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;
? ? ? ? // @Conditional注解表達(dá)式解析類
? ? ? ? this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
? ? ? ? // processor接口集合注冊(cè)
? ? ? ? AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
? ? }
上面可知阵谚,在構(gòu)造函數(shù)初始化的過(guò)程中桌吃,順便還注冊(cè)了?BeanDefinitionRegistryPostProcessor集合洒扎,這個(gè)接口會(huì)在?ApplicationContext#refresh()操作中會(huì)被統(tǒng)一調(diào)用。
2讳推、AnnotationConfigUtils#registerAnnotationConfigProcessors()
public static Set registerAnnotationConfigProcessors(
? ? ? ? ? ? BeanDefinitionRegistry registry, @Nullable Object source) {
? ? ? ? ....
? ? ? ? ....
? ? ? ? Set beanDefs = new LinkedHashSet(4);
? ? ? ? // @Configuration注解解析處理類
? ? ? ? if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
? ? ? ? ? ? RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
? ? ? ? ? ? def.setSource(source);
? ? ? ? ? ? beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
? ? ? ? }
? ? ? ? // @Autowired注解解析處理類
? ? ? ? if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
? ? ? ? ? ? RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
? ? ? ? ? ? def.setSource(source);
? ? ? ? ? ? beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
? ? ? ? }
? ? ? ? // @Required注解解析處理類
? ? ? ? if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
? ? ? ? ? ? RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
? ? ? ? ? ? def.setSource(source);
? ? ? ? ? ? beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
? ? ? ? }
? ? ? ? // @WebServiceDef/@EJB/@Resource/@PostConstruct/@PreDestroy注解解析
? ? ? ? if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
? ? ? ? ? ? RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
? ? ? ? ? ? def.setSource(source);
? ? ? ? ? ? beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
? ? ? ? }
? ? ? ? // JPA注解解析
? ? ? ? if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
? ? ? ? ? ? RootBeanDefinition def = new RootBeanDefinition();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
? ? ? ? ? ? ? ? ? ? ? ? AnnotationConfigUtils.class.getClassLoader()));
? ? ? ? ? ? }
? ? ? ? ? ? catch (ClassNotFoundException ex) {
? ? ? ? ? ? ? ? throw new IllegalStateException(
? ? ? ? ? ? ? ? ? ? ? ? "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
? ? ? ? ? ? }
? ? ? ? ? ? def.setSource(source);
? ? ? ? ? ? beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
? ? ? ? }
? ? ? ? ....
? ? ? ? ....
? ? ? ? return beanDefs;
? ? }
3琅攘、ConfigurationClassPostProcessor#postProcessBeanFactory()
@Override
? ? public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
? ? ? ? int factoryId = System.identityHashCode(beanFactory);
? ? ? ? if (this.factoriesPostProcessed.contains(factoryId)) {
? ? ? ? ? ? throw new IllegalStateException(
? ? ? ? ? ? ? ? ? ? "postProcessBeanFactory already called on this post-processor against " + beanFactory);
? ? ? ? }
? ? ? ? this.factoriesPostProcessed.add(factoryId);
? ? ? ? if (!this.registriesPostProcessed.contains(factoryId)) {
? ? ? ? ? ? // 關(guān)鍵方法
? ? ? ? ? ? processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
? ? ? ? }
? ? ? ? // 對(duì)bean工廠的含Configuration注解實(shí)例進(jìn)行CGLIB代理
? ? ? ? enhanceConfigurationClasses(beanFactory);
? ? ? ? // 對(duì)類型為ImportAware的bean進(jìn)行額外處理
? ? ? ? beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
? ? }
4、ConfigurationClassPostProcessor#?processConfigBeanDefinitions
* Build and validate a configuration model based on the registry of
? ? * {@link Configuration} classes.
? ? */
? ? public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
? ? ? ? List configCandidates = new ArrayList();
? ? ? ? String[] candidateNames = registry.getBeanDefinitionNames();
? ? ? ? // 遍歷注冊(cè)在bean工廠上的所有bean爆袍,篩選出未加載過(guò)的@Configuration類
? ? ? ? for (String beanName : candidateNames) {
? ? ? ? ? ? // 避免重復(fù)加載
? ? ? ? ? ? BeanDefinition beanDef = registry.getBeanDefinition(beanName);
? ? ? ? ? ? if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
? ? ? ? ? ? ? ? ? ? ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
? ? ? ? ? ? ? ? if (logger.isDebugEnabled()) {
? ? ? ? ? ? ? ? ? ? logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
? ? ? ? ? ? ? ? configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 無(wú)@Configuration注解bean則直接返回
? ? ? ? if (configCandidates.isEmpty()) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? ....
? ? ? ? ....
? ? ? ? // 解析@Configuration
? ? ? ? ConfigurationClassParser parser = new ConfigurationClassParser(
? ? ? ? ? ? ? ? this.metadataReaderFactory, this.problemReporter, this.environment,
? ? ? ? ? ? ? ? this.resourceLoader, this.componentScanBeanNameGenerator, registry);
? ? ? ? Set candidates = new LinkedHashSet(configCandidates);
? ? ? ? Set alreadyParsed = new HashSet(configCandidates.size());
? ? ? ? do {
? ? ? ? ? ? parser.parse(candidates);
? ? ? ? ? ? parser.validate();
? ? ? ? ? ? ...
? ? ? ? ? ? candidates.clear();
? ? ? ? ? ? // 檢查是否含有新的bean沒(méi)有被解析
? ? ? ? ? ? if (registry.getBeanDefinitionCount() > candidateNames.length) {
? ? ? ? ? ? ? ? ...
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? while (!candidates.isEmpty());
? ? ? ? ...
? ? }
5、ConfigurationClassParser#parse()
public void parse(Set configCandidates) {
? ? ? ? this.deferredImportSelectors = new LinkedList();
? ? ? ? // 對(duì)不同類型的bean調(diào)用不同的parse負(fù)載方法
? ? ? ? for (BeanDefinitionHolder holder : configCandidates) {
? ? ? ? ? ? BeanDefinition bd = holder.getBeanDefinition();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? if (bd instanceof AnnotatedBeanDefinition) {
? ? ? ? ? ? ? ? ? ? parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
? ? ? ? ? ? ? ? ? ? parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? else {
? ? ? ? ? ? ? ? ? ? parse(bd.getBeanClassName(), holder.getBeanName());
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? catch (BeanDefinitionStoreException ex) {
? ? ? ? ? ? ? ? throw ex;
? ? ? ? ? ? }
? ? ? ? ? ? catch (Throwable ex) {
? ? ? ? ? ? ? ? throw new BeanDefinitionStoreException(
? ? ? ? ? ? ? ? ? ? ? ? "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // 針對(duì)DeferredImportSelector延遲選擇類作下處理
? ? ? ? processDeferredImportSelectors();
? ? }
6作郭、ConfigurationClassParser#doProcessConfigurationClass()
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
? ? ? ? ? ? throws IOException {
? ? ? ? // Recursively process any member (nested) classes first
? ? ? ? processMemberClasses(configClass, sourceClass);
? ? ? ? // Process any @PropertySource annotations
? ? ? ? for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
? ? ? ? ? ? ? ? sourceClass.getMetadata(), PropertySources.class,
? ? ? ? ? ? ? ? org.springframework.context.annotation.PropertySource.class)) {
? ? ? ? ? ? if (this.environment instanceof ConfigurableEnvironment) {
? ? ? ? ? ? ? ? processPropertySource(propertySource);
? ? ? ? ? ? }
? ? ? ? ? ? else {
? ? ? ? ? ? ? ? logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
? ? ? ? ? ? ? ? ? ? ? ? "]. Reason: Environment must implement ConfigurableEnvironment");
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // Process any @ComponentScan annotations
? ? ? ? Set componentScans = AnnotationConfigUtils.attributesForRepeatable(
? ? ? ? ? ? ? ? sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
? ? ? ? if (!componentScans.isEmpty() &&
? ? ? ? ? ? ? ? !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
? ? ? ? ? ? for (AnnotationAttributes componentScan : componentScans) {
? ? ? ? ? ? ? ? // The config class is annotated with @ComponentScan -> perform the scan immediately
? ? ? ? ? ? ? ? Set scannedBeanDefinitions =
? ? ? ? ? ? ? ? ? ? ? ? this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
? ? ? ? ? ? ? ? // Check the set of scanned definitions for any further config classes and parse recursively if needed
? ? ? ? ? ? ? ? for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
? ? ? ? ? ? ? ? ? ? BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
? ? ? ? ? ? ? ? ? ? if (bdCand == null) {
? ? ? ? ? ? ? ? ? ? ? ? bdCand = holder.getBeanDefinition();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
? ? ? ? ? ? ? ? ? ? ? ? parse(bdCand.getBeanClassName(), holder.getBeanName());
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // Process any @Import annotations
? ? ? ? processImports(configClass, sourceClass, getImports(sourceClass), true);
? ? ? ? // Process any @ImportResource annotations
? ? ? ? AnnotationAttributes importResource =
? ? ? ? ? ? ? ? AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
? ? ? ? if (importResource != null) {
? ? ? ? ? ? String[] resources = importResource.getStringArray("locations");
? ? ? ? ? ? Class readerClass = importResource.getClass("reader");
? ? ? ? ? ? for (String resource : resources) {
? ? ? ? ? ? ? ? String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
? ? ? ? ? ? ? ? configClass.addImportedResource(resolvedResource, readerClass);
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // Process individual @Bean methods
? ? ? ? Set beanMethods = retrieveBeanMethodMetadata(sourceClass);
? ? ? ? for (MethodMetadata methodMetadata : beanMethods) {
? ? ? ? ? ? configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
? ? ? ? }
? ? ? ? // Process default methods on interfaces
? ? ? ? processInterfaces(configClass, sourceClass);
? ? ? ? // Process superclass, if any
? ? ? ? if (sourceClass.getMetadata().hasSuperClass()) {
? ? ? ? ? ? String superclass = sourceClass.getMetadata().getSuperClassName();
? ? ? ? ? ? if (superclass != null && !superclass.startsWith("java") &&
? ? ? ? ? ? ? ? ? ? !this.knownSuperclasses.containsKey(superclass)) {
? ? ? ? ? ? ? ? this.knownSuperclasses.put(superclass, configClass);
? ? ? ? ? ? ? ? // Superclass found, return its annotation metadata and recurse
? ? ? ? ? ? ? ? return sourceClass.getSuperClass();
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? // No superclass -> processing is complete
? ? ? ? return null;
? ? }