定义Spring Bean
什么是BeanDefinition?
BeanDefinition是Spring Framwork中定义的Bean的配置元信息接口,包括:
Bean的类名
Bean行为配置元素,如作用域、自动绑定的模式、生命周期回调等
其他Bean引用,又可称作合作者(Collaborators)或者依赖(Dependencies)
配置设置,比如Bean属性(Properties)
BeanDefinition元信息
属性(Property)
Class | Bean全类名,必须是具体类,不能用抽象类或接口
Name | Bean的名称或者ID
Scope | Bean的作用域(如:singleton、prototype等)
Constructor arguments | Bean构造器参数(用于依赖注入)
Propertes | Bean属性设置(用于
BeanDefinition构建
通过BeanDefinitionBuilder
通过AbstractBeanDefinition以及派生类
通过BeanDefinitionBuilder构建
1 2 3 4 5 6 7 8 9 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class); beanDefinitionBuilder .addPropertyValue("id" , 1 ) .addPropertyValue("name" , "小马哥" ); BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
通过AbstractBeanDefinition以及派生类构建
1 2 3 4 5 6 7 8 9 10 11 12 13 GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition(); genericBeanDefinition.setBeanClass(User.class); MutablePropertyValues propertyValues = new MutablePropertyValues(); propertyValues .add("id" , 1 ) .add("name" , "小马哥" ); genericBeanDefinition.setPropertyValues(propertyValues);
命令Spring Bean
Bean 的名称
每个 Bean 拥有一个或多个标识符(identifiers),这些标识符在 Bean 所在的容器必须是唯一
的。通常,一个 Bean 仅有一个标识符,如果需要额外的,可考虑使用别名(Alias)来扩充。
在基于 XML 的配置元信息中,开发人员可用 id 或者 name 属性来规定 Bean 的 标识符。通常
Bean 的 标识符由字母组成,允许出现特殊字符。如果要想引入 Bean 的别名的话,可在
name 属性使用半角逗号(“,”)或分号(“;”) 来间隔。
Bean 的 id 或 name 属性并非必须制定,如果留空的话,容器会为 Bean 自动生成一个唯一的
名称。Bean 的命名尽管没有限制,不过官方建议采用驼峰的方式,更符合 Java 的命名约定。
Bean 名称生成器(BeanNameGenerator)
由 Spring Framework 2.0.3 引入,框架內建两种实现:
DefaultBeanNameGenerator:默认通用 BeanNameGenerator 实现
AnnotationBeanNameGenerator:基于注解扫描的 BeanNameGenerator 实现,起始于
Spring Framework 2.5,关联的官方文档:
With component scanning in the classpath, Spring generates bean names for unnamed components,
following the rules described earlier: essentially, taking the simple class name and turning its initial
character to lower-case. However, in the (unusual) special case when there is more than one
character and both the first and second characters are upper case, the original casing gets preserved.
These are the same rules as defined by java.beans.Introspector.decapitalize (which Spring uses here).
Spring Bean别名
Bean 别名(Alias)的价值
• 复用现有的 BeanDefinition
• 更具有场景化的命名方法,比如:
BeanDefinition 注册
XML 配置元信息
• <bean name=”…” … />
Java 注解配置元信息
• @Bean
• @Component
• @Import
Java API 配置元信息
• 命名方式:BeanDefinitionRegistry#registerBeanDefinition(String,BeanDefinition)
• 非命名方式:
BeanDefinitionReaderUtils#registerWithGeneratedName(AbstractBeanDefinition,Be
anDefinitionRegistry)
• 配置类方式:AnnotatedBeanDefinitionReader#register(Class…)
1 2 3 4 5 6 7 8 9 public static void main (String[] args) { BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/bean-definitions-context.xml" ); User user = beanFactory.getBean("user" , User.class); User xiaomageUser = beanFactory.getBean("xiaomage-user" , User.class); System.out.println("xiaomage-user 是否与 user Bean 相同:" + (user == xiaomageUser)); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class AnnotationBeanDefinitionDemo1 { public static void main (String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.register(Config.class); applicationContext.refresh(); System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class)); System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class)); applicationContext.close(); } public static class Config { @Bean (name = {"user" , "xiaomage-user" }) public User user () { User user = new User(); user.setId(1L ); user.setName("小马哥" ); return user; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public class AnnotationBeanDefinitionDemo2 { public static void main (String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.register(Config.class); applicationContext.refresh(); System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class)); System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class)); applicationContext.close(); } @Component public static class Config { @Bean (name = {"user" , "xiaomage-user" }) public User user () { User user = new User(); user.setId(1L ); user.setName("小马哥" ); return user; } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Import (AnnotationBeanDefinitionDemo.Config.class)public class AnnotationBeanDefinitionDemo3 { public static void main (String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.register(AnnotationBeanDefinitionDemo3.class); applicationContext.refresh(); System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class)); System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class)); applicationContext.close(); } @Component public static class Config { @Bean (name = {"user" , "xiaomage-user" }) public User user () { User user = new User(); user.setId(1L ); user.setName("小马哥" ); return user; } } }