生活随笔
收集整理的這篇文章主要介紹了
定位Bean 扫描路径
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在Spring 中管理注解Bean 定義的容器有兩個: AnnotationConfigApplicationContext 和AnnotationConfigWebApplicationContex。這兩個類是專門處理Spring 注解方式配置的容器,直接依賴于注解作為容器配置信息來源的IOC 容器。AnnotationConfigWebApplicationContext 是
AnnotationConfigApplicationContext 的Web 版本,兩者的用法以及對注解的處理方式幾乎沒有差別。現在我們以AnnotationConfigApplicationContext 為例看看它的源碼:
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {//保存一個讀取注解的Bean定義讀取器,并將其設置到容器中private final AnnotatedBeanDefinitionReader reader;//保存一個掃描指定類路徑中注解Bean定義的掃描器,并將其設置到容器中private final ClassPathBeanDefinitionScanner scanner;//默認構造函數,初始化一個空容器,容器不包含任何 Bean 信息,需要在稍后通過調用其register()//方法注冊配置類,并調用refresh()方法刷新容器,觸發容器對注解Bean的載入、解析和注冊過程public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {super(beanFactory);this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}//最常用的構造函數,通過將涉及到的配置類傳遞給該構造函數,以實現將相應配置類中的Bean自動注冊到容器中public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {this();register(annotatedClasses);refresh();}//該構造函數會自動掃描以給定的包及其子包下的所有類,并自動識別所有的Spring Bean,將其注冊到容器中public AnnotationConfigApplicationContext(String... basePackages) {this();scan(basePackages);refresh();}@Overridepublic void setEnvironment(ConfigurableEnvironment environment) {super.setEnvironment(environment);this.reader.setEnvironment(environment);this.scanner.setEnvironment(environment);}//為容器的注解Bean讀取器和注解Bean掃描器設置Bean名稱產生器public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {this.reader.setBeanNameGenerator(beanNameGenerator);this.scanner.setBeanNameGenerator(beanNameGenerator);getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);}//為容器的注解Bean讀取器和注解Bean掃描器設置作用范圍元信息解析器public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {this.reader.setScopeMetadataResolver(scopeMetadataResolver);this.scanner.setScopeMetadataResolver(scopeMetadataResolver);}//為容器注冊一個要被處理的注解Bean,新注冊的Bean,必須手動調用容器的//refresh()方法刷新容器,觸發容器對新注冊的Bean的處理public void register(Class<?>... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");this.reader.register(annotatedClasses);}//掃描指定包路徑及其子包下的注解類,為了使新添加的類被處理,必須手動調用//refresh()方法刷新容器public void scan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");this.scanner.scan(basePackages);}public <T> void registerBean(Class<T> annotatedClass, Object... constructorArguments) {registerBean(null, annotatedClass, constructorArguments);}public <T> void registerBean(@Nullable String beanName, Class<T> annotatedClass, Object... constructorArguments) {this.reader.doRegisterBean(annotatedClass, null, beanName, null,bd -> {for (Object arg : constructorArguments) {bd.getConstructorArgumentValues().addGenericArgumentValue(arg);}});}@Overridepublic <T> void registerBean(@Nullable String beanName, Class<T> beanClass, @Nullable Supplier<T> supplier,BeanDefinitionCustomizer... customizers) {this.reader.doRegisterBean(beanClass, supplier, beanName, null, customizers);}}
通過上面的源碼分析,我們可以看啊到Spring 對注解的處理分為兩種方式:
1)、直接將注解Bean 注冊到容器中
可以在初始化容器時注冊;也可以在容器創建之后手動調用注冊方法向容器注冊,然后通過手動刷新容器,使得容器對注冊的注解Bean 進行處理。
2)、通過掃描指定的包及其子包下的所有類
在初始化注解容器時指定要自動掃描的路徑,如果容器創建以后向給定路徑動態添加了注解Bean,則需要手動調用容器掃描的方法,然后手動刷新容器,使得容器對所注冊的Bean 進行處理。
接下來,將會對兩種處理方式詳細分析其實現過程。
?
總結
以上是生活随笔為你收集整理的定位Bean 扫描路径的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。