前言
Spring是分层的 Java SE/EE应用full- stack轻量级开源框架,以IoC(Inversion of Control:反转控制)和AOP( Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring MVC和持久层 Spring JDBC以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE企业应用开源框架。
定义spring bean
什么是BeanDefinition?
BeanDefinition是spring Framework中定义Bean的配置元信息接口,包含:
Bean的类名,包含包名,即全限定名
Bean的行为配置元素,如作用域、自动绑定模式、生命周期回调等
其他Bean引用,又可称作合作者(Collaborators)或者依赖(Dependencies)
配置设置,比如Bean属性(Properties)
BeanDefinition的元信息
| 属性(Property) | 说明 |
| ------------------------ | ---------------------------------------------- |
| Class | Bean的全类名,必须是具体类,不能是抽象类或接口 |
| Name | Bean的名称或ID |
| Scope | Bean的作用域(如Singlton,prototype等) |
| Constructor arguments | Bean的构造器参数(用于依赖注入) |
| Properties | Bean的属性设置(用于依赖注入) |
| Autowiring mode | Bean的自动绑定模式(如:通过名称byName) |
| Lazy initialization mode | Bean的延迟初始化模块(延迟和非延迟) |
| Initialization method | Bean的初始化回调方法名称 |
| Destruction method | Bean销毁回调方法名称 |
BeanDefinition的构建-
通过BeanDefinitionBuilder
spring源码部分如下:/** * Programmatic means of constructing * {@link org.springframework.beans.factory.config.BeanDefinition BeanDefinitions} * using the builder pattern. Intended primarily for use when implementing Spring 2.0 * {@link org.springframework.beans.factory.xml.NamespaceHandler NamespaceHandlers}. * * @author Rod Johnson * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 */ public final class BeanDefinitionBuilder { /** * Create a new {@code BeanDefinitionBuilder} used to construct a {@link GenericBeanDefinition}. */ public static BeanDefinitionBuilder genericBeanDefinition() { return new BeanDefinitionBuilder(new GenericBeanDefinition()); } /** * Create a new {@code BeanDefinitionBuilder} used to construct a {@link GenericBeanDefinition}. * @param beanClassName the class name for the bean that the definition is being created for */ public static BeanDefinitionBuilder genericBeanDefinition(String beanClassName) { BeanDefinitionBuilder builder = new BeanDefinitionBuilder(new GenericBeanDefinition()); builder.beanDefinition.setBeanClassName(beanClassName); return builder; } .........
我们可以通过这个类进行BeanDefinition的构建:
//通过BeanDefinitionBuilder进行构建 BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(User.class); //通过属性设置 beanDefinitionBuilder.addPropertyValue("name","zhangsan"); beanDefinitionBuilder.addPropertyValue("id",1L); //获取BeanDefinition实例 BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
通过AbstractBeanDefinition以及派生类
//通过AbstractBeanDefiniton以及派生类
GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
//设置Bean的类型
genericBeanDefinition.setBeanClass(User.class);
//通过MutablePropertyValues批量操作属性
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name","zhangsan");
propertyValues.addPropertyValue("id",1L);
//通过 set MutablePropertyValues 批量操作属性
genericBeanDefinition.setPropertyValues(propertyValues);
命名spring bean
Bean的名称
- 每个Bean拥有一个或多个标识符(identifiters),这些标识符在Bean所在的容器必须是唯一的。通常,一个Bean仅有一个标识符,如果需要额外的,可以考虑使用别名(Alias)来扩充。
- 在基于XML的配置信息中,开发人员可以通过id或者name属性来规定Bean的标识符。通常Bean的标识符由字母组成,允许出现特殊字符。如果要引入Bean的别名的话,可在name属性使用半角逗号,或分号来分隔。
- Bean的id或name属性并非必须制定,如果留空的话,容器会为Bean自动生成一个唯一的名称。Bean的命名尽管没有限制,不过官方建议使用驼峰命名的方式,更符合Java的命名约定。
Bean的名称生成器(BeanNameGenrator)
由Spring framework 2.0.3引入,框架内建两种实现: - DefaultBeanNameGenarator:默认通过BeanNameGenarator实现
BeanNameGenarator的接口定义如下:
DefaultBeanNameGenarator实现如下:/** * Strategy interface for generating bean names for bean definitions. * * @author Juergen Hoeller * @since 2.0.3 */ public interface BeanNameGenerator { /** * Generate a bean name for the given bean definition. * @param definition the bean definition to generate a name for * @param registry the bean definition registry that the given definition * is supposed to be registered with * @return the generated bean name */ String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry); }
可以看到这个一个单例模式的实现,但是构造方法并没有私有化,为的是兼容之前的版本。** * Default implementation of the {@link BeanNameGenerator} interface, delegating to * {@link BeanDefinitionReaderUtils#generateBeanName(BeanDefinition, BeanDefinitionRegistry)}. * * @author Juergen Hoeller * @since 2.0.3 */ public class DefaultBeanNameGenerator implements BeanNameGenerator { /** * A convenient constant for a default {@code DefaultBeanNameGenerator} instance, * as used for {@link AbstractBeanDefinitionReader} setup. * @since 5.2 */ public static final DefaultBeanNameGenerator INSTANCE = new DefaultBeanNameGenerator(); @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return BeanDefinitionReaderUtils.generateBeanName(definition, registry); } }
- AnnotationBeanNameGenarator:基于注解扫描的BeanNameGenarator实现,起始于Spring framework 2.5
public class AnnotationBeanNameGenerator implements BeanNameGenerator {
/**
* A convenient constant for a default {@code AnnotationBeanNameGenerator} instance,
* as used for component scanning purposes.
* @since 5.2
*/
public static final AnnotationBeanNameGenerator INSTANCE = new AnnotationBeanNameGenerator();
private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";
private final Map> metaAnnotationTypesCache = new ConcurrentHashMap<>();
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
if (definition instanceof AnnotatedBeanDefinition) {
String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
if (StringUtils.hasText(beanName)) {
// Explicit bean name found.
return beanName;
}
}
// Fallback: generate a unique default bean name.
return buildDefaultBeanName(definition, registry);
}
........
Spring Bean的别名
Bean别名(Alias)的价值
- 复用现有的BeanDefinition
- 更具有场景化的命名方法,比如: