@EnableCache解析

1,451 阅读2分钟

@EnableCchae的定义:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(CachingConfigurationSelector.class) public @interface EnableCaching

功能:自动开启SpringCache,即导入四个核心的类到IoC容器之中: ProxyCachingConfiguration:作为一个@Configuration标记的导入Cache的核心类 CacheInterceptor:实现AOP的拦截器,即对相关的方法进行拦截 AnnotationCacheOperationSource:对与Cache的注解进行解析,建立一个方法与Cache规定的CacheOperation相关联 BeanFactoryCacheOperationSourceAdvisor:最为重要的类,定义了Cache相关的pointcut和advice之间的联系,在实现Cache的AOP代理的时候,将之与InfrastructureAdvisorAutoProxyCreator后置处理器相关联,通过后置处理器来判断一个类的方法是否需要使用Cache的AOP代理。

起到关键作用的就是这个@Import里面的内容,在准备BeanDefinition阶段ConfigurationClassParser在对@Configuration解析的过程中对@EnableCache实际上就是对@Import进行解析注解处理。

processImports(configClass, sourceClass, getImports(sourceClass), filter, true); 
// 这里通过getImports获取@Import()注解里面的内容 
// 传过去即是importCandidates,表示需要导入的候取元素

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
		Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
		boolean checkForCircularImports) {

	if (importCandidates.isEmpty()) {
		return;
	}

	if (checkForCircularImports && isChainedImportOnStack(configClass)) {
		this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
	}
	else {
		this.importStack.push(configClass);
		try {
			for (SourceClass candidate : importCandidates) {
			    // 候取导入的元素是ImportSelector类型的
				if (candidate.isAssignable(ImportSelector.class)) {
					// Candidate class is an ImportSelector -> delegate to it to determine imports
					Class<?> candidateClass = candidate.loadClass();
					// 获取ImportSelector
					ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
							this.environment, this.resourceLoader, this.registry);
					Predicate<String> selectorFilter = selector.getExclusionFilter();
					if (selectorFilter != null) {
						exclusionFilter = exclusionFilter.or(selectorFilter);
					}
					// DefeeredImportSelector是处理@EnableAutoConfiguration注解的特殊ImportSelector
					if (selector instanceof DeferredImportSelector) {
						this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
					}
					else {
					// 调用导入class
						String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
						Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
						// 在处理现在导入的类
						processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
					}
				}
				// 如果不是看是否能注册到容器之中
				else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
					// Candidate class is an ImportBeanDefinitionRegistrar ->
					// delegate to it to register additional bean definitions
					Class<?> candidateClass = candidate.loadClass();
					ImportBeanDefinitionRegistrar registrar =
							ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
									this.environment, this.resourceLoader, this.registry);
					configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
				}
				else {
					// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
					// process it as an @Configuration class
					this.importStack.registerImport(
							currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
					processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
				}
			}
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(
					"Failed to process import candidates for configuration class [" +
					configClass.getMetadata().getClassName() + "]", ex);
		}
		finally {
			this.importStack.pop();
		}
	}
}

下面是

public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> {


@Override
public String[] selectImports(AdviceMode adviceMode) {
    // adviceMode是其父类定义的,即AOP采用什么方式实现,一般采用PROXY代理模式
	switch (adviceMode) {
		case PROXY:
		    // 获取资源
			return getProxyImports();
		case ASPECTJ:
			return getAspectJImports();
		default:
			return null;
	}
}

private String[] getProxyImports() {
	List<String> result = new ArrayList<>(3);
	result.add(AutoProxyRegistrar.class.getName());
	// 这个是Cache模块的关键
	result.add(ProxyCachingConfiguration.class.getName());
	if (jsr107Present && jcacheImplPresent) {
		result.add(PROXY_JCACHE_CONFIGURATION_CLASS);
	}
	return StringUtils.toStringArray(result);
}

}

// 下面这个类将会通过selectImport()导入进IoC容器之中 @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyCachingConfiguration extends AbstractCachingConfiguration {

@Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
// 这个类时实现Cache AOP代理的关键
public BeanFactoryCacheOperationSourceAdvisor cacheAdvisor() {
	BeanFactoryCacheOperationSourceAdvisor advisor = new BeanFactoryCacheOperationSourceAdvisor();
	advisor.setCacheOperationSource(cacheOperationSource());
	advisor.setAdvice(cacheInterceptor());
	if (this.enableCaching != null) {
		advisor.setOrder(this.enableCaching.<Integer>getNumber("order"));
	}
	return advisor;
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public CacheOperationSource cacheOperationSource() {
	return new AnnotationCacheOperationSource();
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
//
public CacheInterceptor cacheInterceptor() {
	CacheInterceptor interceptor = new CacheInterceptor();
	interceptor.configure(this.errorHandler, this.keyGenerator, this.cacheResolver, this.cacheManager);
	interceptor.setCacheOperationSource(cacheOperationSource());
	return interceptor;
}

}

调用堆栈