記一次@Component無效的問題

1. 問題描述

具體的業務就不說了

抽象出來的問題是, 有一個類 標記了 @Aspect@Component ,但是切面卻沒有起作用

applicationContext.getBean(XXX.class);
//找不到這個bean,很奇怪

2. 查原因

  1. 打斷點,查看BeanFactory裏面的所有BeanDefinition,發現沒有XXX這個類
  2. BeanFactory使用了一個Map來存儲所有的BeanDefinition, 考慮是否是key重複的原因
  3. 找到生成Bean名稱的類 org.springframework.context.annotation.AnnotationBeanNameGenerator#generateBeanName ,發現如果未指定名稱,則使用,如下代碼來生成Bean的名字
protected String buildDefaultBeanName(BeanDefinition definition) {
    String shortClassName = ClassUtils.getShortName(definition.getBeanClassName());
    return Introspector.decapitalize(shortClassName);
}
  1. 打一個條件斷點,查看輸出的名字, 發現真的有兩個BeanDefinition名字重複了,包名不一樣,類名是一樣的
  2. 問題找到了,在掃描所有BeanDefinition的時候, 重名的BeanDefinition把先掃描到放入Map的給覆蓋掉了

3. 解決

直接給 重名的Bean改個名字 @Component("YYYYY") 即可

4. Spring環境啓動的方法棧如下

//這裏是棧底
org.springframework.context.support.AbstractApplicationContext#refresh
org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
org.springframework.context.support.AbstractApplicationContext#refreshBeanFactory
org.springframework.context.support.AbstractRefreshableApplicationContext#loadBeanDefinitions
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#scan
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan


//String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//這裏是生成Bean的名字的步驟
org.springframework.context.annotation.AnnotationBeanNameGenerator#generateBeanName


org.springframework.beans.factory.support.BeanDefinitionRegistry#registerBeanDefinition
//這裏是把BeanDefinition往map放的步驟
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
//這裏是棧頂
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章