前提:使用注解@Configuration是为了提前初始化一批特性,不要将其作为@Component注解特性使用。
java
class ConfigurationClassParser {
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass){
...
// 处理注解 @ComponentScan,即启动类@ComponentScan存在的所有属性
AnnotationMetadata am = sourceClass.getMetadata();
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
am, ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(am, ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
String className = sourceClass.getMetadata().getClassName();
//通过启动类获取到扫描路径,即启动类所在的路径以及该路径下所有的子路径
Set<BeanDefinitionHolder> scannedBeanDefinitions = componentScanParser.parse(componentScan, className);
// 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();
}
// 确定候选类的模式Full or Lite
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
...
return null;
}
}
1、获取@Configuration候选类
java
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {//basePackages就是启动类所在的路径以及其子路径
// 利用类加载器获取路径basePackage下所有候选类的资源URL~Resource
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata sm = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(sm.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {// 确保容器注册表中只能存在当前bean唯一的BeanDefinition
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(sm, definitionHolder, registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
}
每个候选类初始被封装成ScannedGenericBeanDefinition
,核心属性就是候选类的资源URL~Resource。但是在添加容器注册表之前为啥进一步封住成BeanDefinitionHolder
?
2、容器注册表注册候选类的BeanDefinition
java
public abstract class BeanDefinitionReaderUtils {
//registry:DefaultListableBeanFactory
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry){
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
}
3、确定候选类的模式之Full or Lite
java
abstract class ConfigurationClassUtils {
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory msf) {
...
AnnotationMetadata metadata;
String className = (AnnotatedBeanDefinition) beanDef).getMetadata().getClassName();
if (beanDef instanceof AnnotatedBeanDefinition && className.equals(className)) {
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
metadata = AnnotationMetadata.introspect(beanClass);
}else {
MetadataReader metadataReader = msf.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
//查看候选类中属性proxyBeanMethods,默认值为true
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
// 如果proxyBeanMethods = true则为Full默认
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}else if (config != null || isConfigurationCandidate(metadata)) {
//否则为Lite模式
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}else {
return false;
}
...
return true;
}
}
4、候选类尝试Cglib代理处理
java
final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> bp) {
...
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
...
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(bp, beanFactory);
}
...
}
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// ConfigurationClassPostProcessor
postProcessor.postProcessBeanFactory(beanFactory);
}
}
}
java
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
...
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {// Full模式
...
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
if (configBeanDefs.isEmpty()) {
return;
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
// org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.getBeanClass();
//候选类生成最终Cglib代理类
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
beanDef.setBeanClass(enhancedClass);
}
}
}
}