@yulongsun
2018-05-09T01:26:57.000000Z
字数 7320
阅读 1713
Spring源码走读
由Spring3.0引入,用于处理Spring注解。
org.springframework.context.annotation.AnnotationConfigApplicationContext
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {private final AnnotatedBeanDefinitionReader reader;private final ClassPathBeanDefinitionScanner scanner;public AnnotationConfigApplicationContext() {//创建Bean定义读取器this.reader = new AnnotatedBeanDefinitionReader(this);//创建Bean定义扫描器this.scanner = new ClassPathBeanDefinitionScanner(this);}public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {super(beanFactory);this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}public AnnotationConfigApplicationContext(Class... annotatedClasses) {this();this.register(annotatedClasses);this.refresh();}public AnnotationConfigApplicationContext(String... basePackages) {this();this.scan(basePackages);this.refresh();}public void setEnvironment(ConfigurableEnvironment environment) {super.setEnvironment(environment);this.reader.setEnvironment(environment);this.scanner.setEnvironment(environment);}public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {this.reader.setBeanNameGenerator(beanNameGenerator);this.scanner.setBeanNameGenerator(beanNameGenerator);this.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", beanNameGenerator);}public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {this.reader.setScopeMetadataResolver(scopeMetadataResolver);this.scanner.setScopeMetadataResolver(scopeMetadataResolver);}protected void prepareRefresh() {this.scanner.clearCache();super.prepareRefresh();}//新注册Bean.需调用refresh()刷新,触发容器对新注册Bean的处理。public void register(Class... annotatedClasses) {Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");this.reader.register(annotatedClasses);}public void scan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");this.scanner.scan(basePackages);}}
public class AnnotatedBeanDefinitionReader {......public void register(Class<?>... annotatedClasses) {for (Class<?> annotatedClass : annotatedClasses) {registerBean(annotatedClass);}}public void registerBean(Class<?> annotatedClass) {registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);}public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {registerBean(annotatedClass, null, qualifiers);}public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);abd.setScope(scopeMetadata.getScopeName());String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}}
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {...public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment) {// 调用父类的构造方法,设置过滤规则super(useDefaultFilters, environment);// 为容器设置Bean定义的注册器this.registry = registry;// 如果注册器是资源加载器,则为容器设置资源加载器if (this.registry instanceof ResourceLoader) {setResourceLoader((ResourceLoader) this.registry);}}public int scan(String... basePackages) {//获取已注册的Bean个数int beanCountAtScanStart = this.registry.getBeanDefinitionCount();//启动扫描器 扫描指定packagedoScan(basePackages);// 注册注解配置处理器if (this.includeAnnotationConfig) {AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}//返回新注册的Bean个数return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);}protected Set<BeanDefinitionHolder> doScan(String... basePackages) {//创建一个集合,存放扫描到Bean定义的封装类Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();for (String basePackage : basePackages) {//获取符合条件的BeanDefinitionSet<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {//获取Bean的作用域ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);//为Bean设置注解配置的作用域candidate.setScope(scopeMetadata.getScopeName());//为Bean设置名字String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);//【重要】 如果扫描到的不是注解的Beanif (candidate instanceof AbstractBeanDefinition) {postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}//【重要】 如果扫描到的是注解的Bean,调用工具类处理通用的注解if (candidate instanceof AnnotatedBeanDefinition) {AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}//根据Bean名称,检查Bean是否需要在容器中注册。if (checkCandidate(beanName, candidate)) {BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);//根据注解中配置的作用域,为Bean设置相应的代理模式definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);//向容器中注册扫描到的BeanregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}....}
1、定制注册表
public class CustomBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry);// 指定include注解AnnotationTypeFilter includeFiliter = new AnnotationTypeFilter(CustomComponent.class);scanner.addIncludeFilter(includeFiliter);// 指定扫描包String[] basePackages = {"win.yulongsun.demo.spring.di.scan"};scanner.scan(basePackages);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}}
2、自定义注解
public @interface CustomComponent {}
3、使用注解
@CustomComponentpublic class Foo {public void say() {System.out.println("i am class");}}
4、测试
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = {CustomBeanDefinitionRegistry.class})public class CustomBeanDefinitionRegistryTest {@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testAssertBean() {Assert.notNull(applicationContext.getBean(Foo.class));Foo bean = applicationContext.getBean(Foo.class);bean.say();}}
1、Spring对注解(Annotation)处理源码分析1——扫描和读取Bean定义
2、Spring(25)——ClassPathBeanDefinitionScanner