spring事务执行流程分析_5(注解形式 advisor等前置对象的生成)

news2024/12/26 9:19:03

调用beanFactory处理器

依旧进入刷新refresh方法AbstractApplicationContext#refresh ->

在上一篇文章spring事务执行流程分析_4(注解形式 @EnableTransactionManagement的作用)
解析@EnableTransactionManagement注解就是在此方法进行的,也就是在会注册

名字:internalAutoProxyCreator 类型:InfrastructureAdvisorAutoProxyCreator
名字:internalTransactionAdvisor 类型:BeanFactoryTransactionAttributeSourceAdvisor
名字:transactionAttributeSource 类型:TransactionAttributeSource
名字:transactionInterceptor 类型:TransactionInterceptor
的bean

然后调用各种beanFactory处理器AbstractApplicationContext#invokeBeanFactoryPostProcessors

执行beanFactory处理器AbstractApplicationContext#invokeBeanFactoryPostProcessors

/***省略部分代码*/

//postProcessorNames = org.springframework.context.annotation.internalConfigurationAnnotationProcessor(类型为ConfigurationClassPostProcessor)
String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 遍历处理所有符合规则的postProcessorNames
for (String ppName : postProcessorNames) {
    // 检测是否实现了PriorityOrdered接口
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        // 获取名字对应的bean实例,添加到currentRegistryProcessors中
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        // 将要被执行的BFPP名称添加到processedBeans,避免后续重复执行
        processedBeans.add(ppName);
    }
}
// 按照优先级进行排序操作
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到registryProcessors中,用于最后执行postProcessBeanFactory方法
registryProcessors.addAll(currentRegistryProcessors);
// 遍历currentRegistryProcessors,执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

/***省略部分代码*/

分析invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)这一行接着深入调用直到ConfigurationClassPostProcessor#processConfigBeanDefinitions

ConfigurationClassPostProcessor#processConfigBeanDefinitions

/**
 * 构建和验证一个类是否被@Configuration修饰,并做相关的解析工作
 *
 * 如果你对此方法了解清楚了,那么springboot的自动装配原理就清楚了
 *
 * Build and validate a configuration model based on the registry of
 * {@link Configuration} classes.
 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	// 创建存放BeanDefinitionHolder的对象集合
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	// 当前registry就是DefaultListableBeanFactory,获取所有已经注册的BeanDefinition的beanName
	String[] candidateNames = registry.getBeanDefinitionNames();

	// 遍历所有要处理的beanDefinition的名称,筛选对应的beanDefinition(被注解修饰的)
	for (String beanName : candidateNames) {
		// 获取指定名称的BeanDefinition对象
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);
		// 如果beanDefinition中的configurationClass属性不等于空,那么意味着已经处理过,输出日志信息
		if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		}
		// 判断当前BeanDefinition是否是一个配置类,并为BeanDefinition设置属性为lite或者full,此处设置属性值是为了后续进行调用
		// 如果Configuration配置proxyBeanMethods代理为true则为full
		// 如果加了@Bean、@Component、@ComponentScan、@Import、@ImportResource注解,则设置为lite
		// 如果配置类上被@Order注解标注,则设置BeanDefinition的order属性值
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			// 添加到对应的集合对象中
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// Return immediately if no @Configuration classes were found
	// 如果没有发现任何配置类,则直接返回
	if (configCandidates.isEmpty()) {
		return;
	}

	// Sort by previously determined @Order value, if applicable
	// 如果适用,则按照先前确定的@Order的值排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});

	// Detect any custom bean name generation strategy supplied through the enclosing application context
	// 判断当前类型是否是SingletonBeanRegistry类型
	SingletonBeanRegistry sbr = null;
	if (registry instanceof SingletonBeanRegistry) {
		// 类型的强制转换
		sbr = (SingletonBeanRegistry) registry;
		// 判断是否有自定义的beanName生成器
		if (!this.localBeanNameGeneratorSet) {
			// 获取自定义的beanName生成器
			BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
					AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
			// 如果有自定义的命名生成策略
				if (generator != null) {
				//设置组件扫描的beanName生成策略
				this.componentScanBeanNameGenerator = generator;
				// 设置import bean name生成策略
				this.importBeanNameGenerator = generator;
			}
		}
	}

	// 如果环境对象等于空,那么就重新创建新的环境对象
	if (this.environment == null) {
		this.environment = new StandardEnvironment();
	}

	// Parse each @Configuration class
	// 实例化ConfigurationClassParser类,并初始化相关的参数,完成配置类的解析工作
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	// 创建两个集合对象,
	// 存放相关的BeanDefinitionHolder对象
	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	// 存放扫描包下的所有bean
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {
		// 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition
		parser.parse(candidates);
		// 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIB
		parser.validate();

		// 获取所有的bean,包括扫描的bean对象,@Import导入的bean对象
		Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
		// 清除掉已经解析处理过的配置类
		configClasses.removeAll(alreadyParsed);

		// Read the model and create bean definitions based on its content
		// 判断读取器是否为空,如果为空的话,就创建完全填充好的ConfigurationClass实例的读取器
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		// 核心方法,将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
		this.reader.loadBeanDefinitions(configClasses);
		// 添加到已经处理的集合中
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		// 这里判断registry.getBeanDefinitionCount() > candidateNames.length的目的是为了知道reader.loadBeanDefinitions(configClasses)这一步有没有向BeanDefinitionMap中添加新的BeanDefinition
		// 实际上就是看配置类(例如AppConfig类会向BeanDefinitionMap中添加bean)
		// 如果有,registry.getBeanDefinitionCount()就会大于candidateNames.length
		// 这样就需要再次遍历新加入的BeanDefinition,并判断这些bean是否已经被解析过了,如果未解析,需要重新进行解析
		// 这里的AppConfig类向容器中添加的bean,实际上在parser.parse()这一步已经全部被解析了
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> alreadyParsedClasses = new HashSet<>();
			for (ConfigurationClass configurationClass : alreadyParsed) {
				alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
			}
			// 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
			for (String candidateName : newCandidateNames) {
				if (!oldCandidateNames.contains(candidateName)) {
					BeanDefinition bd = registry.getBeanDefinition(candidateName);
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
							!alreadyParsedClasses.contains(bd.getBeanClassName())) {
						candidates.add(new BeanDefinitionHolder(bd, candidateName));
					}
				}
			}
			candidateNames = newCandidateNames;
		}
	}
	while (!candidates.isEmpty());

	// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
	if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
		sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
	}

	if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
		// Clear cache in externally provided MetadataReaderFactory; this is a no-op
		// for a shared cache since it'll be cleared by the ApplicationContext.
		((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
	}
}

可以看到此方法会解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition

分析parser.parse(candidates) 这一行,此时的解析的bean是TransactionConfig,然后接着会执行到ConfigurationClassParser#doProcessConfigurationClass

ConfigurationClassParser#doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(
		ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
		throws IOException {
	// @Configuration继承了@Component
	if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
		// Recursively process any member (nested) classes first
		// 递归处理内部类,因为内部类也是一个配置类,配置类上有@configuration注解,该注解继承@Component,if判断为true,调用processMemberClasses方法,递归解析配置类中的内部类
		processMemberClasses(configClass, sourceClass, filter);
	}

	// Process any @PropertySource annotations
	// 如果配置类上加了@PropertySource注解,那么就解析加载properties文件,并将属性添加到spring上下文中
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), PropertySources.class,
			org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		else {
			logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
					"]. Reason: Environment must implement ConfigurableEnvironment");
		}
	}

	// Process any @ComponentScan annotations
	// 处理@ComponentScan或者@ComponentScans注解,并将扫描包下的所有bean转换成填充后的ConfigurationClass
	// 此处就是将自定义的bean加载到IOC容器,因为扫描到的类可能也添加了@ComponentScan和@ComponentScans注解,因此需要进行递归解析
	Set<AnnotationAttributes> 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
			// 解析@ComponentScan和@ComponentScans配置的扫描的包所包含的类
			// 比如 basePackages = com.mashibing, 那么在这一步会扫描出这个包及子包下的class,然后将其解析成BeanDefinition
			// (BeanDefinition可以理解为等价于BeanDefinitionHolder)
			Set<BeanDefinitionHolder> scannedBeanDefinitions =
					this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
			// Check the set of scanned definitions for any further config classes and parse recursively if needed
			// 通过上一步扫描包com.mashibing,有可能扫描出来的bean中可能也添加了ComponentScan或者ComponentScans注解.
			//所以这里需要循环遍历一次,进行递归(parse),继续解析,直到解析出的类上没有ComponentScan和ComponentScans
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				// 判断是否是一个配置类,并设置full或lite属性
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					// 通过递归方法进行解析
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// Process any @Import annotations
	// 处理@Import注解
	processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

	// Process any @ImportResource annotations
	// 处理@ImportResource注解,导入spring的配置文件
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// Process individual @Bean methods
	// 处理加了@Bean注解的方法,将@Bean方法转化为BeanMethod对象,保存再集合中
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// Process default methods on interfaces
	// 处理接口的默认方法实现,从jdk8开始,接口中的方法可以有自己的默认实现,因此如果这个接口的方法加了@Bean注解,也需要被解析
	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;
}

注意下@EnableTransactionManagement注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement

所以在执行ConfigurationClassParser#doProcessConfigurationClass中的处理@Import注解
在上一篇文章spring事务执行流程分析_4(注解形式 @EnableTransactionManagement的作用)解析@EnableTransactionManagement注解就是在processImports(configClass, sourceClass, getImports(sourceClass), filter, true)这一行中执行的。

此时的beanDefinitionMap:
在这里插入图片描述
此时的singletonObjects:
在这里插入图片描述

执行BeanPostProcessors处理器

依旧进入刷新refresh方法开始
AbstractApplicationContext#refresh ->
AbstractApplicationContext#registerBeanPostProcessors ->

AbstractApplicationContext#registerBeanPostProcessors

AbstractApplicationContext#registerBeanPostProcessors

在这个方法中会生成 名字:internalAutoProxyCreator 类型:InfrastructureAdvisorAutoProxyCreator的bean

/**
 * 注册beanPostProcessor
 * @param beanFactory
 * @param applicationContext
 */
public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 找到所有实现了BeanPostProcessor接口的类
    //0   org.springframework.context.annotation.internalAutowiredAnnotationProcessor
    //1   org.springframework.context.annotation.internalCommonAnnotationProcessor
    //2   org.springframework.aop.config.internalAutoProxyCreator
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    // 记录下BeanPostProcessor的目标计数
    // 此处为什么要+1呢,原因非常简单,在此方法的最后会添加一个BeanPostProcessorChecker的类
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    // 定义存放实现了PriorityOrdered接口的BeanPostProcessor集合
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 定义存放spring内部的BeanPostProcessor
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // 定义存放实现了Ordered接口的BeanPostProcessor的name集合
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 定义存放普通的BeanPostProcessor的name集合
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    // 遍历beanFactory中存在的BeanPostProcessor的集合postProcessorNames,
    for (String ppName : postProcessorNames) {
        // 如果ppName对应的BeanPostProcessor实例实现了PriorityOrdered接口,则获取到ppName对应的BeanPostProcessor的实例添加到priorityOrderedPostProcessors中
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        // 如果ppName对应的BeanPostProcessor实例没有实现PriorityOrdered接口,但是实现了Ordered接口,那么将ppName对应的bean实例添加到orderedPostProcessorNames中
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        } else {
            // 否则将ppName添加到nonOrderedPostProcessorNames中
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    // 首先,对实现了PriorityOrdered接口的BeanPostProcessor实例进行排序操作
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 注册实现了PriorityOrdered接口的BeanPostProcessor实例添加到beanFactory中
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    // 注册所有实现Ordered的beanPostProcessor
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        // 根据ppName找到对应的BeanPostProcessor实例对象
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        // 将实现了Ordered接口的BeanPostProcessor添加到orderedPostProcessors集合中
        orderedPostProcessors.add(pp);
        // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 对实现了Ordered接口的BeanPostProcessor进行排序操作
    sortPostProcessors(orderedPostProcessors, beanFactory);
    //  注册实现了Ordered接口的BeanPostProcessor实例添加到beanFactory中
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    // 创建存放没有实现PriorityOrdered和Ordered接口的BeanPostProcessor的集合
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    // 遍历集合
    for (String ppName : nonOrderedPostProcessorNames) {
        // 根据ppName找到对应的BeanPostProcessor实例对象
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        // 将没有实现PriorityOrdered和Ordered接口的BeanPostProcessor添加到nonOrderedPostProcessors集合中
        nonOrderedPostProcessors.add(pp);
        // 如果ppName对应的BeanPostProcessor实例也实现了MergedBeanDefinitionPostProcessor接口,那么则将ppName对应的bean实例添加到internalPostProcessors中
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    //  注册没有实现PriorityOrdered和Ordered的BeanPostProcessor实例添加到beanFactory中
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    // 将所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor进行排序操作
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 注册所有实现了MergedBeanDefinitionPostProcessor类型的BeanPostProcessor到beanFactory中
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    // 注册ApplicationListenerDetector到beanFactory中
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

此时的singletonObjects:
在这里插入图片描述

初始化剩下的单实例(非懒加载的)

依旧进入刷新refresh方法开始
AbstractApplicationContext#refresh ->
AbstractApplicationContext#finishBeanFactoryInitialization ->
DefaultListableBeanFactory#preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
        logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    // 将所有BeanDefinition的名字创建一个集合
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    // 触发所有非延迟加载单例bean的初始化,遍历集合的对象
    for (String beanName : beanNames) {
        // 合并父类BeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 条件判断,抽象,单例,非懒加载
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 判断是否实现了FactoryBean接口
            if (isFactoryBean(beanName)) {
                // 根据&+beanName来获取具体的对象
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                // 进行类型转换
                if (bean instanceof FactoryBean) {
                    FactoryBean<?> factory = (FactoryBean<?>) bean;
                    // 判断这个FactoryBean是否希望立即初始化
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(
                                (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                                getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    //  如果希望急切的初始化,则通过beanName获取bean实例
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
            }
            else {
                // 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    // 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
    for (String beanName : beanNames) {
        // 获取beanName对应的bean实例
        Object singletonInstance = getSingleton(beanName);
        // 判断singletonInstance是否实现了SmartInitializingSingleton接口
        if (singletonInstance instanceof SmartInitializingSingleton) {
            // 类型转换
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            // 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

到这里就是创建出真正的对象bean了,其中会把
名字:internalTransactionAdvisor 类型:BeanFactoryTransactionAttributeSourceAdvisor
名字:transactionAttributeSource 类型:TransactionAttributeSource
名字:transactionInterceptor 类型:TransactionInterceptor
的对象创建出来

分析getBean(beanName)此方法是真正创建对象的逻辑
AbstractBeanFactory#getBean ->

AbstractAutowireCapableBeanFactory#createBean ->
AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation ->
AbstractAutoProxyCreator#postProcessBeforeInstantiation

AbstractAutoProxyCreator#postProcessBeforeInstantiation

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
	Object cacheKey = getCacheKey(beanClass, beanName);

	if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
		//查缓存,是否有处理过了,不管是不是需要通知增强的,只要处理过了就会放里面
		if (this.advisedBeans.containsKey(cacheKey)) {
			return null;
		}
		if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
			// 要跳过的直接设置FALSE
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return null;
		}
	}

	// Create proxy here if we have a custom TargetSource.
	// Suppresses unnecessary default instantiation of the target bean:
	// The TargetSource will handle target instances in a custom fashion.
	TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
	if (targetSource != null) {
		if (StringUtils.hasLength(beanName)) {
			this.targetSourcedBeans.add(beanName);
		}
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
		Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	return null;
}

AbstractAutoProxyCreator#shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}

之前在xml解析的时候执行到shouldSkip方法时会将adviosr、pointcout创建好,而注解的方式这里不会创建

advisor对象的创建

从初始化剩下的单实例(非懒加载的)方法开始分析,beanName为transactionConfig时,调用链路为
DefaultListableBeanFactory#preInstantiateSingletons ->
AbstractAutowireCapableBeanFactory#createBean ->
AbstractAutowireCapableBeanFactory#doCreateBean ->
AbstractAutowireCapableBeanFactory#initializeBean ->
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

InfrastructureAdvisorAutoProxyCreator的第一次postProcessAfterInitialization方法的wrapIfNecessary中创建BeanFactoryTransactionAttributeSourceAdvisor,由于InfrastructureAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreatorAbstractAdvisorAutoProxyCreator 继承了 AbstractAutoProxyCreator,所以显示是AbstractAutoProxyCreator#postProcessAfterInitialization

AbstractAutoProxyCreator#postProcessAfterInitialization ->
AbstractAutoProxyCreator#wrapIfNecessary

/**
 * 先判断是否已经处理过,是否需要跳过,跳过的话直接就放进advisedBeans里,表示不进行代理,如果这个bean处理过了,获取通知拦截器,然后开始进行代理
 *
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	// 如果已经处理过,直接返回
	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
		return bean;
	}
	// 如果不需要增强,则直接返回
	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
		return bean;
	}
	// 判断给定的bean类是否代表一个基础设施类,基础设施类不应代理,或者配置了指定bean不需要自动代理
	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

	// Create proxy if we have advice.
	// 根据目标对象和容器中所有的advisor做判断匹配返回符合目标对象的advisor
	// 如果存在增强方法则创建代理
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	// 如果获取到了增强则需要针对增强创建代理
	if (specificInterceptors != DO_NOT_PROXY) {
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 创建代理
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}

根据目标对象和容器中所有的advisor做判断匹配返回符合目标对象的advisor,在这个方法中,会创建所有的advisor,并返回和指定的bean匹配的advisor,创建出了名字:internalTransactionAdvisor 类型:BeanFactoryTransactionAttributeSourceAdvisor

分析AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean这行,里面执行了AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

/**
 * 找到所有符合条件的通知对于自动代理的类
 *
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	// 获取所有的增强
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	// 寻找所有增强中适用于bean的增强并应用
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	// 在Advisor集合中添加一个org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR 用于执行事务链时的调用
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		//排序,将org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR排在集合首位
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

获取所有的增强并创建

  1. 因为BeanFactoryTransactionAttributeSourceAdvisor是bean注解的工厂方法,所以要先实例化工厂factoryBean,也就是实例化ProxyTransactionManagementConfiguration
  2. 因为BeanFactoryTransactionAttributeSourceAdvisor工厂方法有参数依赖,所以要注入依赖,创建AnnotationTransactionAttributeSource和TransactionInterceptor实例
  3. 最后反射调用方法创建BeanFactoryTransactionAttributeSourceAdvisor 设置依赖属性

寻找所有增强中适用于bean的增强并应用返回,这时的beanName为transactionConfig,执行后的eligibleAdvisors为空的。所以换成beanName为bookService的时候来分析

分析findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);这一行

AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

protected List<Advisor> findAdvisorsThatCanApply(
		List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

	ProxyCreationContext.setCurrentProxiedBeanName(beanName);
	try {
		// 过滤已经得到的advisors
		return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
	}
	finally {
		ProxyCreationContext.setCurrentProxiedBeanName(null);
	}
}

此方法具体逻辑:

遍历Advisors集合,
在遍历Advisors集合的过程中,遍历这个bean的所有方法,
优先方法上解析的事务注解的属性,会去找父类或者接口的方法,如果存在解析事务注解的属性并放入
AbstractFallbackTransactionAttributeSource的this.attributeCache.put(cacheKey, txAttr);缓存中。
cacheKey:MethodClassKey类型 , public void com.test.tx.annotation.service.impl.BookService.addUser(com.test.tx.entity.User) on class com.test.tx.annotation.service.impl.BookService
txAttr:RuleBasedTransactionAttribute类型, PROPAGATION_REQUIRED,ISOLATION_DEFAULT
将该Advisors放入符合条件的新Advisors

如果没有,再尝试声明该方法的类上搞得注解属性,会去父类或者接口找,如果存在解析事务注解的属性并放入
AbstractFallbackTransactionAttributeSource的this.attributeCache.put(cacheKey, txAttr);缓存中。
cacheKey:MethodClassKey类型 , public void com.test.tx.annotation.service.impl.BookService.addUser(com.test.tx.entity.User) on class com.test.tx.annotation.service.impl.BookService
txAttr:RuleBasedTransactionAttribute类型, PROPAGATION_REQUIRED,ISOLATION_DEFAULT
将该Advisors放入符合条件的新Advisors

将新Advisors集合返回,如果以上都不符合返回的就是空的

执行完后返回AbstractAutoProxyCreator#wrapIfNecessary
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);执行完毕。
如果specificInterceptors 不为空则进行创建动态代理类。
AbstractAutoProxyCreator#createProxy创建完后回到AbstractAutowireCapableBeanFactory#initializeBean返回动态代理类。

到这里后续的和xml中的逻辑相同。

注解形式 事务的初始化流程图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

简单模拟vue实现数据劫持-视图更新双向绑定-2

接上&#xff0c; new一个实例对象&#xff0c;vc&#xff0c;构造函数动态绑定一个空对象&#xff0c;并在构造函数上绑定静态方法 $on进行事件的注册&#xff0c;$emit抛出执行事件 function observe() {// 利用策略模式-可以快速根据特定的事件&#xff0c;执行多个函数th…

最全总结 | 聊聊 Selenium 隐藏浏览器指纹特征的几种方式!

大家好&#xff0c;我是安果&#xff01;我们使用 Selenium 对网页进行爬虫时&#xff0c;如果不做任何处理直接进行爬取&#xff0c;会导致很多特征是暴露的对一些做了反爬的网站&#xff0c;做了特征检测&#xff0c;用来阻止一些恶意爬虫本篇文章将介绍几种常用的隐藏浏览器…

第九层(9):STL之map/multimap

文章目录前情回顾map/multimap概念差别构造函数赋值操作大小操作函数交换函数插入函数删除函数查找函数统计函数排序规则下一座石碑&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后…

三线金叉选股公式,均线、成交量、MACD共振

均线、成交量、MACD三线金叉共振选股公式思路还是比较简单的&#xff0c;分别写出均线金叉、成交量的均量线金叉、MACD的快线和慢线金叉&#xff0c;最后用AND连接这三个条件。 一、编写选股公式所需通达信函数 1、EXIST函数 含义&#xff1a;是否存在 用法&#xff1a;EXIST…

OpenGL | 搭建OpenGL 画画框架

一、搭建OpenGL 画画框架3D场景初始化&#xff08;1&#xff09; 代码void Init() {glMatrixMode(GL_PROJECTION); //将当前矩阵指定为投影矩阵,对投影矩阵操作gluPerspective(50.0f, 800.0f / 600.0f, 0.1f, 1000.0f);//创建一个对称的透视投影矩阵&#xff0c;并且用这个…

世界上最大型的 Demo Drop DJ 比赛来到元宇宙!

简要介绍 WBDD 于 2023 年 1 月 26 日至 2 月 8 日进入元宇宙。 认识世界上最大型的 DJ 比赛获胜者&#xff0c;并在元宇宙中伴随着他们的音乐跳舞。 该体验将是线下活动的延伸&#xff0c;由 Mike Williams 担任活动大使。 体验将对所有人开放。 完成 80% 的任务&#xff…

51单片机简易出租车计费系统仿真设计( proteus仿真+程序+报告+讲解视频)

51单片机简易出租车计费系统仿真设计( proteus仿真程序报告讲解视频&#xff09; 仿真图proteus 8.9及以上 程序编译器&#xff1a;keil 4/keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;S0036 51单片机简易出租车计费系统仿真设计讲解视频1.主要功能&#xff1a;…

MXNet实现图片的样式风格迁移(Style Transfer)

样式迁移就是将一个样式&#xff08;风格&#xff09;应用到一张主图上&#xff0c;改变这张图片的风格&#xff0c;比如说拍摄了一张夜晚的图片&#xff0c;我们可以拿梵高的"星月夜"图片做样式&#xff0c;应用到拍摄的图片上&#xff0c;两者合成后的新图片&#…

linux基本功系列之uptime命令实战

文章目录一. uptime命令介绍二. 语法格式及常用选项三. 参考案例3.1 显示当前系统运行负载情况3.2 显示机器正常运行的时间3.3 显示机器启动时间3.4 关于平均负载的介绍总结前言&#x1f680;&#x1f680;&#x1f680; 想要学好Linux&#xff0c;命令是基本功&#xff0c;企业…

推荐 5 个实用 GitHub 项目

本期推荐开源项目目录&#xff1a;1. AI-For-Beginners2. 一个小巧轻便的 PDF 阅读器3. 开源的智能手表4. 开源内容管理系统5. 程序员海外工作/英文面试手册01AI-For-Beginners之前推荐过 Microsoft 出品的 Web 技术栈课程&#xff0c;本开源项目同样是 Microsoft 的 Azure Clo…

go runtime

go 运行时&#xff0c;也称为 go runtime&#xff0c;类似Java中的JVM虚拟机&#xff0c;不过runtime并非是虚拟机。其本身就是每个 go 程序的一部分&#xff0c;它会跟源码一起编译并链接到目标程序中&#xff0c;即便只写了一个 hello world 程序&#xff0c;这个程序中也包含…

day15 二叉树 | 104、二叉树的最大深度 111、二叉树的最小深度 222、完全二叉树的节点个数

题目 104、二叉树的最大深度 递归法&#xff08;后序&#xff09;&#xff08;必须会&#xff09; // 定义&#xff1a;输入根节点&#xff0c;返回这棵二叉树的最大深度 int maxDepth(TreeNode root) {if (root null) {return 0;}// 利用定义&#xff0c;计算左右子树的最大…

论文笔记:Graph WaveNet for Deep Spatial-Temporal Graph Modeling

IJCAI 2019 1 abstract & intro 时空数据挖掘问题大多数使用邻接矩阵来建模节点之间的属性关系&#xff0c;这种思路的一个基本假设是&#xff1a;节点信息取决于自身和邻居的历史信息。 但这类模型的假设存在着一些问题&#xff1a; 未能充分建模节点之间的依赖关…

宝塔部署springboot,vue,node.js项目

宝塔部署springboot项目&#xff1a; 先将命令转移到jar包所属文件夹中 分为短暂部署和永久部署 短暂部署&#xff1a;java -jar xxx.jar 永久部署&#xff1a;nohup java -jar demo-1.0.0.jar logs_mark.txt 2>&1 & nohup:linux的命令,代表关闭但持续运行 查看898…

52.Isaac教程--操纵杆

操纵杆 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录操纵杆使用游戏机操纵杆使用其他操纵杆使用 Playstation 操纵杆很容易控制运行 Isaac SDK 的机器人&#xff0c;但也可以使用其他控制器。 使用游戏机操纵杆 按照以下步骤校准您的…

微信小程序018小说在线阅读系统书城

管理员的主要功能有&#xff1a; 1.管理员输入账户登陆后台 2.个人中心&#xff1a;管理员修改密码和账户信息 3.用户管理&#xff1a;对注册的用户信息进行删除&#xff0c;查询&#xff0c;添加&#xff0c;修改 4.小说信息管理&#xff1a;对小说信息进行添加&#xff0c;修…

TCP/IP第六章笔记ICMP协议

文章目录6.1 引言6.2 ICMP报文分组格式和类型6.3 ICMP地址掩码请求与应答6.4 ICMP时间戳请求与应答6.5 ICMP端口不可达差错6.6 ICMP的处理&#xff08;4.4BSD系统下&#xff09;6.1 引言 第三章在IP选择路由时&#xff0c;如果一个报文最后限制转发次数用完后还传输不到目的地…

【高并发】- 不可不知道的RPC框架服务通信

前言 前面章节讲解了高并发系统中相关指标、为什么要学习高并发设计思想、高并发系统中每个环节的流量处理等思想。本章节讲解服务通信&#xff0c;来帮助大家更好理解系统间通信过程。 1 RPC框架介绍 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff0…

Win10家庭版和Win10专业版有什么区别?

win10操作系统拥有7个不同的版本&#xff0c;其中win10家庭版和专业版被人们广泛的应用&#xff0c;很多用户都不知道如何区分win10家庭版和专业版&#xff0c;接下来把win10家庭版和专业版有什么不同的地方告诉大家。我们一起来看看吧。 win10家庭版和专业版的区别&#xff1a…

java服务框架高级之微服务保护 Sentinel 限制规则,流控模式,流控效果

初识Sentinel 雪崩问题&#xff1a; 解决雪崩问题的常见方式有四种&#xff1a; 1.超时处理&#xff1a;设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&#xff0c;不会无休止等待 2.舱壁模式&#xff1a;限定每个业务能使用的线程数&#xff0c;避免耗尽…