Spring扫描
@ComponentScan
注解
- 构造扫描器,并配置
ClassPathBeanDefinitionScanner
- 开始扫描
- 拼接扫描路径,获取所有的
class资源
- ASM技术读取
类元数据
,判定是否能成为一个Bean
,并经过过滤器处理,加入候选集
- 去重,生成
BeanDefinition
,注册到容器中
入口
- 初始化Spring时,调用
AbstractApplicationContext
中的refresh
,其中会进行各种初始化
- 对
BeanFactory
进行注册中心的
后置增强时,其中的ConfigurationClassPostProcessor
,会进行@Component
扫描,得到BeanDefinition
,注册到beanFactory

- 解析配置类,解析发现
@ComponentScan
,会扫描对应的路径下的类,获得对应的BeanDefinition
ConfigurationClassPostProcessor
- 通过调用
postProcessBeanDefinitionRegistry
,遍历所有的BeanNames
,checkConfigurationClassCandidate
检查是否为配置类
- 创建一个解析器,进行遍历
parse
, 最终调用doProcessConfigurationClass
,进行配置类解析,解析配置类的注解

- 处理配置类上的
ComponentScan
,获取其各个属性,获取需要解析的路径

- 单个处理
ComponentScan
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
- 还会处理
@Import/@ImportResource/@Bean
,AOP的处理就是通过@Import
导入后置处理器
checkConfigurationClassCandidate
- full模式,有注解
@Configuration
,配置类的Bean为cglib
代理对象,在类中@Bean
发生依赖时,保证只有一个,会先从IOC容器中获取
- lite模式,在类中
@Bean
发生依赖时,如果是通过方法调用,会进行多次生成
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// 存在@Configuration 且 proxyBeanMethods 不为 false,是FULL配置类
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//存在 @Configuration 且 proxyBeanMethods 为 false
//不存在 @Configuration 存在 @Component @ComponentScan @Import @ImportREsource
//不存在 @Configuration 存在 @Bean
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
isConfigurationCandidate

ComponentScanAnnotationParser
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addExcludeFilter(typeFilter);
}
}
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
默认BeanName生成器
AnnotationBeanNameGenerator
为默认的BeanName
生成器
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
return beanName;
}
}
return buildDefaultBeanName(definition, registry);
}
- 获取自定义
BeanName

- 没有自定义
BeanName
的处理
protected String buildDefaultBeanName(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
Assert.state(beanClassName != null, "No bean class name set");
String shortClassName = ClassUtils.getShortName(beanClassName);
return Introspector.decapitalize(shortClassName);
}
- 调用
JDK
方法decapitalize
,首字母小写返回,如果前两个字母大写直接返回
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char[] chars = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
ScopedProxy
- 当一个类被注解为
@Scope(WebApplicationContext.SCOPE_REQUEST)
,只有接收到请求后,才会生成Bean
,而又被需要被注入到另一个Bean
中
Spring
会先创建一个代理对象进行注入,当接收到请求时,真正创建一个Bean
Scope
注解的另一个属性,为这个代理对象以什么方式生成,JDK动态代理/CGLIB
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
- 如果
Scope
没有指定代理模式,会根据ComponentScan
的scopedProxy
的模式,那么就能解决当需要注入,但是又不能生成注入Bean,通过对代理对象进行注入的情况
useDefaultFilters
- 默认为
true
,由Spring
添加三个include
过滤器
@Component
@ManagedBean
@Named

addExcludeFilter
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)}
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = InitExclude.class)}
doScan
ClassPathBeanDefinitionScanner
下,执行扫描逻辑
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.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)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
findCandidateComponents
真正扫描
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
scanCandidateComponents
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
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 {
...处理异常
}
return candidates;
}
isCandidateComponent
,处理过滤器逻辑
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
return (metadata.isIndependent() && (metadata.isConcrete() ||
(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
}
checkCandidate
- 去重,
key-value
形式保存beanDefinition
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
if (!this.registry.containsBeanDefinition(beanName)) {
return true;
}
BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
if (originatingDef != null) {
existingDef = originatingDef;
}
if (isCompatible(beanDefinition, existingDef)) {
return false;
}
throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
}
LookUp
- 拥有
@LookUp
修饰的方法的抽象类,会生成代理对象
- 负责找
Bean
,不管方法内部怎么执行,最终返回属性中的Bean
@Lookup("orderService")
public OrderService init() {
return null;
}
- 当希望对于一个单例
Bean
中,每次调用其中的某个Bean
是多例的,用@LookUp
修饰方法,获取该Bean
- 对于在配置类中
@Bean
,导入的Bean
是使用@Lookup
方法是无效的
ASM机制
- 通过反射获取类信息,包中类太多,启动时需要加载很多类,需要确定该类是否是一个
Bean
- ASM机制不需要加载类,通过字节码规范进行类信息读取
InputStream inputStream = new FileInputStream("/Users/mzx/Desktop/java/spring-source/spring-framework/spring-source-learning/build/classes/java/main/com/java/service/UserService.class")
ClassReader classReader = new ClassReader(inputStream)
System.out.println(classReader.getClassName())
System.out.println(classReader.getSuperName())