上篇博文Spring核心概念之BeanDefinition提到的通常定义Bean三种方式 <bean />、@Bean、@Component(@Service,@Controller)就是通过BeanDefinitionReader读取成BeanDefinition的。BeanDefinitionReader在我们使用Spring时用得少,但在Spring源码中用得多,相当于Spring源码的基础设施。BeanDefinitionReder可分为以下几种:
AnnotededBeanDefinitionReader
可以直接将某个类转换为BeanDefinition,并且会解析该类上的注解。包括:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description,例如:
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(beanFactory);
annotatedBeanDefinitionReader.register(User.class);
beanFactory.getBean("user");
配置类(只是配置类本身不包括@Bean)是由AnnotededBeanDefinitionReader读取成BeanDefinition的
ConfigurationClassBeanDefinitionReader
其实配置类中的@Bean方法是由ConfigurationClassBeanDefinitionReader读取成BeanDefinition。
XmlBeanDefinitionReader
<bean />标签是由XmlBeanDefinitionReader解析成BeanDefinition的,例如:
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
beanFactory.getBean("user");
ClassPathBeanDefinitionScanner
ClassPathBeanDefinitionScanner是扫描器,但是它的作用和BeanDefinitionReader类似,它可以扫描某个包路径,对扫描到的类进行解析。扫描到的类上如果存在@Component注解,那么就会把这个类解析为一个BeanDefinition,例如:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.yanfeng");
System.out.println(context.getBean("orderService"));