一、通过注解方式加载Spring
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanConfig.class);
二、AnnotationConfigApplicationContext初始化reader和scanner,然后加载bean
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses)
->this();
->this.reader = new AnnotatedBeanDefinitionReader(this);
->this.scanner = new ClassPathBeanDefinitionScanner(this);
->register(annotatedClasses);
->this.reader.register(annotatedClasses);
->refresh();
->ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //AbstractApplicationContext
->prepareBeanFactory(beanFactory);
->registerBeanPostProcessors(beanFactory); //AbstractApplicationContext
->finishBeanFactoryInitialization(beanFactory);
三、AnnotatedBeanDefinitionReader注册处理注解的BeanDefinitionRegistryPostProcessor
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
->registerAnnotationConfigProcessors(registry, null);
->RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); //@Config处理类
->RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); //@Autowire处理类
->RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); //@Resource处理类
->RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); //@EventListener处理类
->RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); //也是事件监听
}
}
四、@ComponentScan、@Component、@Service分析
4.1、在已知BeanDefinition列表中获取含@ComponentScan,然后遍历@ComponentScan设置的package
4.2、将含有@Component的类全部注册为BeanDefinition
4.3、@Service继承@Component,所以也会被注册
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
->this.componentScanParser = new ComponentScanAnnotationParser(environment, resourceLoader, componentScanBeanNameGenerator, registry);
do {
parser.parse(candidates);
->for (BeanDefinitionHolder holder : configCandidates)
->parse(bd.getBeanClassName(), holder.getBeanName());
->processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
->sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
->Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
->for (AnnotationAttributes componentScan : componentScans)
->Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
->AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
->
} while (!candidates.isEmpty());
}
}
class ComponentScanAnnotationParser {
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass));
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
4.4、ClassPathScanningCandidateComponentProvider会将Component.class注册到includeFilters,doScan以此为依据
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
}
}
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
->return scanCandidateComponents(basePackage);
->Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
->for (Resource resource : resources)
->MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
->if (isCandidateComponent(metadataReader))
->ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
for (BeanDefinition candidate : candidates) {
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
}
}
}
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
}
}
五、@Configuration和@Bean分析
5.1、扫描出所有含@Configuration的类
5.2、扫描含@Configuration的类的方法,注册含@Bean的方法
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
->public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory)
->Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
->return true;
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
do {
parser.parse(candidates);
//获取扫描出的所有含@Configuration的类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
this.reader.loadBeanDefinitions(configClasses);
->for (ConfigurationClass configClass : configurationModel)
->loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
->for (BeanMethod beanMethod : configClass.getBeanMethods())
->loadBeanDefinitionsForBeanMethod(beanMethod); //将@Bean转换成ConfigurationClassBeanDefinition
->loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
->loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
} while (!candidates.isEmpty());
}
}
class ConfigurationClassBeanDefinitionReader {
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
MethodMetadata metadata = beanMethod.getMetadata();
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
for (String alias : names) {
this.registry.registerAlias(beanName, alias);
}
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
String initMethodName = bean.getString("initMethod");
beanDef.setInitMethodName(initMethodName);
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
BeanDefinition beanDefToRegister = beanDef;
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
}
六、@Resource分析(将含@Resource的成员变量加入依赖)
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
->metadata = buildResourceMetadata(clazz);
metadata.checkConfigMembers(beanDefinition);
->for (InjectedElement element : this.injectedElements)
->beanDefinition.registerExternallyManagedConfigMember(member);
->this.externallyManagedConfigMembers.add(configMember);
}
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
ReflectionUtils.doWithLocalFields(targetClass, field -> {
if (field.isAnnotationPresent(Resource.class)) {
currElements.add(new ResourceElement(field, field, null));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (bridgedMethod.isAnnotationPresent(Resource.class)) {
Class<?>[] paramTypes = method.getParameterTypes();
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new ResourceElement(method, bridgedMethod, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
}