`
234390216
  • 浏览: 10192078 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
A5ee55b9-a463-3d09-9c78-0c0cf33198cd
Oracle基础
浏览量:460734
Ad26f909-6440-35a9-b4e9-9aea825bd38e
springMVC介绍
浏览量:1771658
Ce363057-ae4d-3ee1-bb46-e7b51a722a4b
Mybatis简介
浏览量:1395324
Bdeb91ad-cf8a-3fe9-942a-3710073b4000
Spring整合JMS
浏览量:393854
5cbbde67-7cd5-313c-95c2-4185389601e7
Ehcache简介
浏览量:678180
Cc1c0708-ccc2-3d20-ba47-d40e04440682
Cas简介
浏览量:529236
51592fc3-854c-34f4-9eff-cb82d993ab3a
Spring Securi...
浏览量:1178634
23e1c30e-ef8c-3702-aa3c-e83277ffca91
Spring基础知识
浏览量:461646
4af1c81c-eb9d-365f-b759-07685a32156e
Spring Aop介绍
浏览量:150077
2f926891-9e7a-3ce2-a074-3acb2aaf2584
JAXB简介
浏览量:66795
社区版块
存档分类
最新评论

Spring(25)——ClassPathBeanDefinitionScanner

阅读更多

ClassPathBeanDefinitionScanner继承自ClassPathScanningCandidateComponentProvider,构造时要求指定一个BeanDefinitionRegistry对象,其扩展了一个scan方法,可以同时指定多个要扫描的包。底层在扫描bean定义时还是使用的父类的findCandidateComponents方法,但是扫描后会自动利用持有的BeanDefinitionRegistry自动对bean定义进行注册。注册bean定义的bean名称会使用持有的BeanNameGenerator生成,默认是AnnotationBeanNameGenerator;如果对应的bean定义是AnnotatedBeanDefinition类型的,还会处理对应的一些注解定义。而使用ClassPathScanningCandidateComponentProvider时我们只能获取到对应的bean定义,另外的bean注册等还需要我们来做。

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<BeanDefinitionHolder> doScan(String... basePackages) {
	Assert.notEmpty(basePackages, "At least one base package must be specified");
	Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
	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;
}

假设现有HelloOne和HelloTwo两个类,分别位于包com.elim.learn.spring.bean.registry.one和com.elim.learn.spring.bean.registry.two下,它们类上都标注了HelloAnnotation注解,如果现在需要只扫描包com.elim.learn.spring.bean.registry.one和com.elim.learn.spring.bean.registry.two下类上拥有HelloAnnotation注解的类作为bean,则可以定义如下BeanDefinitionRegistryPostProcessor进行bean扫描。

public class CustomBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry);
		TypeFilter includeFilter = new AnnotationTypeFilter(HelloAnnotation.class);
		scanner.addIncludeFilter(includeFilter);
		String[] basePackages = {"com.elim.learn.spring.bean.registry.one", "com.elim.learn.spring.bean.registry.two"};
		scanner.scan(basePackages);
	}

}

测试代码如下:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={CustomBeanDefinitionRegistry.class})
public class CustomBeanDefinitionRegistryTest {

	@Autowired
	private ApplicationContext applicationContext;
	
	@Test
	public void assertBean() {
		Assert.assertNotNull(this.applicationContext.getBean(HelloOne.class));
		Assert.assertNotNull(this.applicationContext.getBean(HelloTwo.class));
	}
	
}

关于ClassPathBeanDefinitionScanner的更多信息请参考相应的API文档或源码。

(本文由Elim写于2017年9月29日)

0
0
分享到:
评论
1 楼 234390216 2017-09-30  
iteye这个博客主体内容定义的宽度只有700,导致部分代码没有展示出来。iteye现在都没有人维护了,这个需要用户在查看的时候自己通过chrome/firefox的开发者工具调整主体页面的宽度,整个页面调整到1300,主体内容调整到1000可以查看隐藏的内容。

相关推荐

Global site tag (gtag.js) - Google Analytics