AnnotationConfigApplicationContext的带参构造器作为入口。
AnnotationConfigApplicationContext
...
// 参数basePackages为自动扫描的包名
public AnnotationConfigApplicationContext(String... basePackages) {
this();
scan(basePackages);
refresh();
}
...
public AnnotationConfigApplicationContext() {
// 默认调用父类无参构造器,可从继承关系图中查看其父类。
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
间接父类AbstractApplicationContext的无参构造器。
AbstractApplicationContext
...
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
...
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
PathMatchingResourcePatternResolver构造器
PathMatchingResourcePatternResolver
...
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
// 由于AnnotationConfigApplicationContext的父类AbstractApplicationContext继承DefaultResourceLoader,拥有ResourceLoader 的特性,此时的resourceLoader就是AnnotationConfigApplicationContext自己。
this.resourceLoader = resourceLoader;
}
直接父类GenericApplicationContext的无参构造器。
GenericApplicationContext
...
public GenericApplicationContext() {
// 这里直接创建ioc容器,使用的容器是DefaultListableBeanFactory。
this.beanFactory = new DefaultListableBeanFactory();
}
在AnnotationConfigApplicationContext父类构造器的调用完成之后,回到自己的无参构造器中。
AnnotationConfigApplicationContext
...
public AnnotationConfigApplicationContext() {
// AnnotationConfigApplicationContext的父类GenericApplicationContext实现了接口BeanDefinitionRegistry,此时this就是AnnotationConfigApplicationContext。
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
进入AnnotatedBeanDefinitionReader的带参构造器。
AnnotatedBeanDefinitionReader
...
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
...
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {
//调用AbstractApplicationContext的getEnvironment方法创建StandardEnvironment
return ((EnvironmentCapable) registry).getEnvironment();
}
return new StandardEnvironment();
}
...
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;
// 创建ConditionEvaluator
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 向容器中注册注解处理器以用来处理配置的各种注解
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
先看ConditionEvaluator构造器
ConditionEvaluator
...
public ConditionEvaluator(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
...
public ConditionContextImpl(BeanDefinitionRegistry registry, Environment environment, ResourceLoader resourceLoader) {
this.registry = registry;
// 推断出beanFactory
this.beanFactory = deduceBeanFactory(registry);
// 推断出environment
this.environment = (environment != null ? environment : deduceEnvironment(registry));
// 推断出resourceLoader,resourceLoader还是AnnotationConfigApplicationContext自身
this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
}
...
private Environment deduceEnvironment(BeanDefinitionRegistry source) {
if (source instanceof EnvironmentCapable) {
return ((EnvironmentCapable) source).getEnvironment();
}
return null;
}
...
private ResourceLoader deduceResourceLoader(BeanDefinitionRegistry source) {
if (source instanceof ResourceLoader) {
return (ResourceLoader) source;
}
return null;
}
再回到AnnotatedBeanDefinitionReader的构造器中看AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
AnnotationConfigUtils
...
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
...
public static Set registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {
// 获取创建的默认容器
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
// 设置AnnotationAwareOrderComparator,以用来支持@Order,@Priority和实现了org.springframework.core.Ordered接口的类。
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set beanDefs = new LinkedHashSet(4);
// 向容器中注册bean
// beanName:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// beanClass:org.springframework.context.annotation.ConfigurationClassPostProcessor
// 实现的接口是BeanDefinitionRegistryPostProcessor,接口父类BeanFactoryPostProcessor。
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));
}
// 向容器中注册AutowiredAnnotationBeanPostProcessor,bean名称为org.springframework.context.annotation.internalAutowiredAnnotationProcessor
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));
}
// 向容器中注册RequiredAnnotationBeanPostProcessor,bean名称为org.springframework.context.annotation.internalRequiredAnnotationProcessor
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));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
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));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
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));
}
// 向容器中注册EventListenerMethodProcessor,bean名称为org.springframework.context.event.internalEventListenerProcessor
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 向容器中注册DefaultEventListenerFactory,bean名称为org.springframework.context.event.internalEventListenerFactory
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
完成AnnotatedBeanDefinitionReader的创建后,回到AnnotationConfigApplicationContext的无参构造器中,开始创建ClassPathBeanDefinitionScanner,进入构造器。
ClassPathBeanDefinitionScanner
...
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
this(registry, true);
}
...
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
// Environment为AbstractApplicationContext已经创建过的StandardEnvironment
this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}
...
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {
this(registry, useDefaultFilters, environment, (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}
...
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// 以下方法在父类ClassPathScanningCandidateComponentProvider中
if (useDefaultFilters) {
// 注册默认过滤器
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
进入ClassPathScanningCandidateComponentProvider
ClassPathScanningCandidateComponentProvider
...
protected void registerDefaultFilters() {
// Component,以用来处理@Component注解
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 如果没有引入javax.annotation.ManagedBean,会抛出异常被catch,不会被加入到内置过滤器中
this.includeFilters.add(new AnnotationTypeFilter(((Class extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.debug("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
// 如果没有引入javax.inject.Named,会抛出异常被catch,不会被加入到内置过滤器中
this.includeFilters.add(new AnnotationTypeFilter(((Class extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.debug("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
...
public void setEnvironment(Environment environment) {
Assert.notNull(environment, "Environment must not be null");
this.environment = environment;
this.conditionEvaluator = null;
}
...
public void setResourceLoader(ResourceLoader resourceLoader) {
// 资源解析器
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
// 初始化简单的元数据读取器和缓存元数据读取器
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
至此,AnnotationConfigApplicationContext的空参构造器执行完毕,接下来回到带参构造器中看scan方法。
AnnotationConfigApplicationContext
...
public void scan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
// ClassPathBeanDefinitionScanner
this.scanner.scan(basePackages);
}
ClassPathBeanDefinitionScanner的scan方法
ClassPathBeanDefinitionScanner
...
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
// 开始扫描包
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
...
protected Set doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set beanDefinitions = new LinkedHashSet();
for (String basePackage : basePackages) {
// 扫描包获取需要注入到容器的组件 父类ClassPathScanningCandidateComponentProvider的方法
Set candidates = findCandidateComponents(basePackage);
... 限于篇幅 暂时省略
}
进入ClassPathScanningCandidateComponentProvider中的findCandidateComponents方法
ClassPathScanningCandidateComponentProvider
...
public Set findCandidateComponents(String basePackage) {
Set candidates = new LinkedHashSet();
try {
// 解析路径 CLASSPATH_ALL_URL_PREFIX为 classpath*: ,resourcePattern为 **/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 资源解析器开始工作 这里的resourcePatternResolver还是AnnotationConfigApplicationContext自己,调用父类GenericApplicationContext的getResources方法
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
... 限于篇幅 暂时省略
GenericApplicationContext中的getResources方法
GenericApplicationContext
...
@Override
public Resource[] getResources(String locationPattern) throws IOException {
// resourceLoader为null
if (this.resourceLoader instanceof ResourcePatternResolver) {
return ((ResourcePatternResolver) this.resourceLoader).getResources(locationPattern);
}
// 再去父类AbstractApplicationContext中getResources方法
return super.getResources(locationPattern);
}
AbstractApplicationContext中的getResources方法
AbstractApplicationContext
...
@Override
public Resource[] getResources(String locationPattern) throws IOException {
// 在AbstractApplicationContext创建对象时声明过,resourcePatternResolver为PathMatchingResourcePatternResolver,
return this.resourcePatternResolver.getResources(locationPattern);
}
PathMatchingResourcePatternResolver
PathMatchingResourcePatternResolver
...
@Override
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
// true
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// true
// a class path resource (multiple resources for same name possible)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// all class path resources with the given name
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(":") + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
...
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
// 确定根路径
String rootDirPath = determineRootDir(locationPattern);
// 截取掉后缀
String subPattern = locationPattern.substring(rootDirPath.length());
// 再次根据路径获取资源 这次是处理过的路径
Resource[] rootDirResources = getResources(rootDirPath);
// 暂时省略
......
}
...
protected String determineRootDir(String location) {
int prefixEnd = location.indexOf(":") + 1;
int rootDirEnd = location.length();
while (rootDirEnd > prefixEnd && getPathMatcher().isPattern(location.substring(prefixEnd, rootDirEnd))) {
rootDirEnd = location.lastIndexOf('/', rootDirEnd - 2) + 1;
}
if (rootDirEnd == 0) {
rootDirEnd = prefixEnd;
}
return location.substring(0, rootDirEnd);
}
...
@Override
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// a class path resource (multiple resources for same name possible)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// all class path resources with the given name
// 找到路径下所有class
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(":") + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
...
protected Resource[] findAllClassPathResources(String location) throws IOException {
String path = location;
if (path.startsWith("/")) {
path = path.substring(1);
}
Set result = doFindAllClassPathResources(path);
if (logger.isDebugEnabled()) {
logger.debug("Resolved classpath location [" + location + "] to resources " + result);
}
return result.toArray(new Resource[result.size()]);
}
...
protected Set doFindAllClassPathResources(String path) throws IOException {
Set result = new LinkedHashSet(16);
// 类加载器 找到需要被扫描的包对应在在磁盘上的绝对路径
ClassLoader cl = getClassLoader();
Enumeration resourceUrls = (cl != null ? cl.getResources(path) : ClassLoader.getSystemResources(path));
while (resourceUrls.hasMoreElements()) {
URL url = resourceUrls.nextElement();
// UrlResource
result.add(convertClassLoaderURL(url));
}
if ("".equals(path)) {
// The above result is likely to be incomplete, i.e. only containing file system references.
// We need to have pointers to each of the jar files on the classpath as well...
addAllClassLoaderJarRoots(cl, result);
}
return result;
}
...
protected Resource convertClassLoaderURL(URL url) {
return new UrlResource(url);
}
getResources方法看完后继续看findPathMatchingResources方法
PathMatchingResourcePatternResolver
...
protected Resource[] findPathMatchingResources(String locationPattern) throws IOException {
String rootDirPath = determineRootDir(locationPattern);
String subPattern = locationPattern.substring(rootDirPath.length());
// 这里继续
Resource[] rootDirResources = getResources(rootDirPath);
Set result = new LinkedHashSet(16);
for (Resource rootDirResource : rootDirResources) {
rootDirResource = resolveRootDirResource(rootDirResource);
URL rootDirURL = rootDirResource.getURL();
if (equinoxResolveMethod != null) {
if (rootDirURL.getProtocol().startsWith("bundle")) {
rootDirURL = (URL) ReflectionUtils.invokeMethod(equinoxResolveMethod, null, rootDirURL);
rootDirResource = new UrlResource(rootDirURL);
}
}
if (rootDirURL.getProtocol().startsWith(ResourceUtils.URL_PROTOCOL_VFS)) {
result.addAll(VfsResourceMatchingDelegate.findMatchingResources(rootDirURL, subPattern, getPathMatcher()));
}
else if (ResourceUtils.isJarURL(rootDirURL) || isJarResource(rootDirResource)) {
result.addAll(doFindPathMatchingJarResources(rootDirResource, rootDirURL, subPattern));
}
// doFindPathMatchingFileResources载入Resource。从磁盘目录检索其下所有的class,返回FileSystemResource。
else {
result.addAll(doFindPathMatchingFileResources(rootDirResource, subPattern));
}
}
if (logger.isDebugEnabled()) {
logger.debug("Resolved location pattern [" + locationPattern + "] to resources " + result);
}
return result.toArray(new Resource[result.size()]);
}
看完getResources方法,再回到ClassPathScanningCandidateComponentProvider继续看findCandidateComponents方法
ClassPathScanningCandidateComponentProvider
...
public Set findCandidateComponents(String basePackage) {
Set candidates = new LinkedHashSet();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
// 这里继续 上面已经将磁盘路径下的所有class文件载入为FileSystemResource
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
// 获取资源元数据读取器,metadataReaderFactory是上面初始化过的CachingMetadataReaderFactory
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
... 限于篇幅 暂时省略
}
CachingMetadataReaderFactory的getMetadataReader方法
CachingMetadataReaderFactory
...
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {
if (getCacheLimit() <= 0) {
return super.getMetadataReader(resource);
}
synchronized (this.metadataReaderCache) {
MetadataReader metadataReader = this.metadataReaderCache.get(resource);
if (metadataReader == null) {
// 如果缓存中没有,从父类SimpleMetadataReaderFactory获取资源的元数据读取器,并缓存起来。
metadataReader = super.getMetadataReader(resource);
this.metadataReaderCache.put(resource, metadataReader);
}
return metadataReader;
}
}
SimpleMetadataReaderFactory的getMetadataReader方法
SimpleMetadataReaderFactory
...
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}
SimpleMetadataReader的构造器
SimpleMetadataReader
...
SimpleMetadataReader(Resource resource, ClassLoader classLoader) throws IOException {
InputStream is = new BufferedInputStream(resource.getInputStream());
ClassReader classReader;
try {
classReader = new ClassReader(is);
}
catch (IllegalArgumentException ex) {
throw new NestedIOException("ASM ClassReader failed to parse class file - " + "probably due to a new Java class file version that isn't supported yet: " + resource, ex);
}
finally {
is.close();
}
// 这个类比较关键 后续根据类上的注解判断类是否应当加入到容器时,就是从这里取得类上的注解元数据
AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader);
// ASM字节码技术处理 访问者模式 构造数据
classReader.accept(visitor, ClassReader.SKIP_DEBUG);
this.annotationMetadata = visitor;
// (since AnnotationMetadataReadingVisitor extends ClassMetadataReadingVisitor)
this.classMetadata = visitor;
this.resource = resource;
}
回到ClassPathScanningCandidateComponentProvider,在获取到元数据读取器之后,继续往下看。
ClassPathScanningCandidateComponentProvider
...
public Set findCandidateComponents(String basePackage) {
Set candidates = new LinkedHashSet();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
// 这里继续 根据资源元数据读取器判断是否是需要的组件
if (isCandidateComponent(metadataReader)) {
... 限于篇幅 暂时省略
isCandidateComponent方法
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// excludeFilters中没有添加过任何过滤器
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return false;
}
}
// ClassPathScanningCandidateComponentProvider在创建对象的时候往includeFilters中添加了一个AnnotationTypeFilter类型的默认过滤器,以用来处理@component注解
for (TypeFilter tf : this.includeFilters) {
// 调用AnnotationTypeFilter父类AbstractTypeHierarchyTraversingFilter的match方法
if (tf.match(metadataReader, this.metadataReaderFactory)) {
return isConditionMatch(metadataReader);
}
}
return false;
}
...
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) {
this.conditionEvaluator = new ConditionEvaluator(getRegistry(), getEnvironment(), getResourceLoader());
}
return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
}
进入AbstractTypeHierarchyTraversingFilter的match方法
AbstractTypeHierarchyTraversingFilter
...
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
// This method optimizes avoiding unnecessary creation of ClassReaders
// as well as visiting over those readers.
// 匹配注解 子类AnnotationTypeFilter重写的方法
if (matchSelf(metadataReader)) {
return true;
}
ClassMetadata metadata = metadataReader.getClassMetadata();
if (matchClassName(metadata.getClassName())) {
return true;
}
if (this.considerInherited) {
if (metadata.hasSuperClass()) {
// Optimization to avoid creating ClassReader for super class.
Boolean superClassMatch = matchSuperClass(metadata.getSuperClassName());
if (superClassMatch != null) {
if (superClassMatch.booleanValue()) {
return true;
}
}
else {
// Need to read super class to determine a match...
try {
if (match(metadata.getSuperClassName(), metadataReaderFactory)) {
return true;
}
}
catch (IOException ex) {
logger.debug("Could not read super class [" + metadata.getSuperClassName() + "] of type-filtered class [" + metadata.getClassName() + "]");
}
}
}
}
if (this.considerInterfaces) {
for (String ifc : metadata.getInterfaceNames()) {
// Optimization to avoid creating ClassReader for super class
Boolean interfaceMatch = matchInterface(ifc);
if (interfaceMatch != null) {
if (interfaceMatch.booleanValue()) {
return true;
}
}
else {
// Need to read interface to determine a match...
try {
if (match(ifc, metadataReaderFactory)) {
return true;
}
}
catch (IOException ex) {
logger.debug("Could not read interface [" + ifc + "] for type-filtered class [" + metadata.getClassName() + "]");
}
}
}
}
return false;
}
AnnotationTypeFilter
AnnotationTypeFilter
...
@Override
protected boolean matchSelf(MetadataReader metadataReader) {
// 获取当前资源的注解元数据
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
return metadata.hasAnnotation(this.annotationType.getName()) ||
(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
}
AnnotationMetadataReadingVisitor
AnnotationMetadataReadingVisitor
...
@Override
public boolean hasAnnotation(String annotationName) {
// 判断是否包含@component annotationSet开始时为空
return this.annotationSet.contains(annotationName);
}
...
@Override
public boolean hasMetaAnnotation(String metaAnnotationType) {
// 获取元数据中所有注解。例如@controller、@service这一类的注解,这些注解上有标注@component 。在metaAnnotationMap中,key是controller或者service,value是component 。这里就是为什么@controller、@service会被扫描的原因
Collection> allMetaTypes = this.metaAnnotationMap.values();
for (Set metaTypes : allMetaTypes) {
if (metaTypes.contains(metaAnnotationType)) {
return true;
}
}
return false;
}
看完isCandidateComponent之后,再回到ClassPathScanningCandidateComponentProvider往下。
ClassPathScanningCandidateComponentProvider
...
public Set findCandidateComponents(String basePackage) {
Set candidates = new LinkedHashSet();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
// 这里继续 构造基础的扫描BeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
// 基础检查
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
// 添加到集合中
candidates.add(sbd);
}
else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);
}
}
else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
// 返回包下所有应当被加入到容器中的BeanDefinition
return candidates;
}
回到最初的ClassPathBeanDefinitionScanner的doScan方法中
ClassPathBeanDefinitionScanner
...
protected Set doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set beanDefinitions = new LinkedHashSet();
for (String basePackage : basePackages) {
Set candidates = findCandidateComponents(basePackage);
// 这里继续 上面findCandidateComponents已经找到包下所有需要加入到容器中的BeanDefinition
for (BeanDefinition candidate : candidates) {
// 解析元数据以获取scope
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 获取beanName,这里从注解元数据中,根据配置返回bean名称(是否有别名)。
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
// true
if (candidate instanceof AbstractBeanDefinition) {
// 当前bean设置默认属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
// true
if (candidate instanceof AnnotatedBeanDefinition) {
// util中处理bean上的普通注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
// 构造BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// util中获取bean元注解中的配置,以决定是否需要代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注入bean到容器中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
...
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
// 其中lazyInit默认false
beanDefinition.applyDefaults(this.beanDefinitionDefaults);
if (this.autowireCandidatePatterns != null) {
beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
}
}
AnnotationBeanNameGenerator,获取bean名称
AnnotationBeanNameGenerator
...
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
// 根据注解推断出beanName
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// Fallback: generate a unique default bean name.
return buildDefaultBeanName(definition, registry);
}
...
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
AnnotationMetadata amd = annotatedDef.getMetadata();
Set types = amd.getAnnotationTypes();
String beanName = null;
for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
// 从注解元数据中,取名称
if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
Object value = attributes.get("value");
if (value instanceof String) {
String strVal = (String) value;
if (StringUtils.hasLength(strVal)) {
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
beanName = strVal;
}
}
}
}
return beanName;
}
...
protected boolean isStereotypeWithNameValue(String annotationType,
Set metaAnnotationTypes, Map attributes) {
boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||
(metaAnnotationTypes != null && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME)) ||
annotationType.equals("javax.annotation.ManagedBean") ||
annotationType.equals("javax.inject.Named");
return (isStereotype && attributes != null && attributes.containsKey("value"));
}
AnnotationConfigUtils,处理普通注解、创建代理bean
AnnotationConfigUtils
...
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
processCommonDefinitionAnnotations(abd, abd.getMetadata());
}
// 处理要加入到容器中的类上标注的各种注解
static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
if (metadata.isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(metadata, Lazy.class).getBoolean("value"));
}
else if (abd.getMetadata() != metadata && abd.getMetadata().isAnnotated(Lazy.class.getName())) {
abd.setLazyInit(attributesFor(abd.getMetadata(), Lazy.class).getBoolean("value"));
}
if (metadata.isAnnotated(Primary.class.getName())) {
abd.setPrimary(true);
}
if (metadata.isAnnotated(DependsOn.class.getName())) {
abd.setDependsOn(attributesFor(metadata, DependsOn.class).getStringArray("value"));
}
if (abd instanceof AbstractBeanDefinition) {
AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
if (metadata.isAnnotated(Role.class.getName())) {
absBd.setRole(attributesFor(metadata, Role.class).getNumber("value").intValue());
}
if (metadata.isAnnotated(Description.class.getName())) {
absBd.setDescription(attributesFor(metadata, Description.class).getString("value"));
}
}
}
// 创建代理bean
static BeanDefinitionHolder applyScopedProxyMode(ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
return definition;
}
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
最后回到ClassPathBeanDefinitionScanner的scan方法中
ClassPathBeanDefinitionScanner
...
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
doScan(basePackages);
// Register annotation config processors, if necessary.
// /true
if (this.includeAnnotationConfig) {
// util中往容器中注册注解配置处理器。在AnnotatedBeanDefinitionReader的构造器中已经执行过。
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
至此,所有的需要往容器中直接注入的bean都已经注入到容器中,但不包括在配置类(@Configuration修饰的类)中声明的bean,不包括使用@import导入的bean。这些形式的bean都要等到处理它们依附的bean时才会处理它们。