spring核心之BeanDefinition
Posted keep-go-on
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring核心之BeanDefinition相关的知识,希望对你有一定的参考价值。
BeanDefinition
什么是BeanDefinition ?
BeanDefinition顾名思义是spring的bean定义,spring创建bean时根据BeanDefinition的描述来创建bean,因此它是Spring的一个核心概念。
BeanDefinition有很多属性来描述bean :
- beanClass。它表示bean的类型。
- Scope,它表示bean的作用域。
- isLazy,表示bean是否需要懒加载。
- dependsOn,表示创建该bean时需要依赖其他bean。
- primary,表示bean为主bean。
- initMethod,表示bean的初始化方法。
beanClass
beanClass表示bean的类型,例如 : UserService.class、GroupController.class等,spring在创建bean时会根据该属性实例化对象。
Scope
scope属性表示bean的作用域,它有两个常见选项 singleton
和prototype
:
- singleton表示该bean是个单例bean(默认)。
- prototype表示该bean是个原型bean。
实际上官方说scope是有5个类型,
singleton
、prototype
、request
、session
和global session
。但是在ConfigurableBeanFactory
中仅定义了singleton
和prototype
,因此最常见的属性其实就是单例和原型。
ConfigurableBeanFactory 中定义的scope类型
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
单例bean
单例bean顾名思义就是使用单例模式创建的bean。该bean一旦被创建就会存在缓存中,后续任何对象调用该bean都不会创建新的bean实例,而是都使用这个对象。spring创建bean时默认就是采用单例模式。
原型bean
每次都会创建出新的对象,使用注解创建原型bean方法如下 :
@Component
@Scope("prototype")
spring的
AbstractBeanFactory
对象的doGetBean
方法负责创建bean,到BeanFactory总结时会解析一下。
isLazy
isLazy表示bean是否需要懒加载:
首先原型bean上面已经说明了,是使用的时候创建新的实例,因此对于原型bean,isLazy不起作用。
对于单例bean,如果声明了需要懒加载,则在bean第一个被调用getBean时创建bean,如果不需要懒加载则在spring启动过程中初始化生成bean。
通常可以使用
@Lazy
注解来解决循环依赖的问题,但是循环依赖本身就该高耦合
的表现,因此解决循环依赖还行建议遵循单一职责原则
,在逻辑与结构上避免循环依赖
dependsOn
dependsOn表示在创建该bean时是需要依赖其他bean。在创建这个bean时其他依赖bean需要先创建完成。
primary
primary表示bean为主bean。spring中一个bean类型可以有多个bean实例,如果在进行依赖注入时,如果根据类型找到了多个bean,这时需要判断是否存在主bean,如果存在就直接将这个bean注入给属性,如果没有主bean就会抛出异常。
initMethodName
initMethodName表示bean的初始化方法,bean的生命周期中,有个步骤叫做bean的初始化,这个过程中会调用bean的initMethodName
方法,我们在编写程序时可以通过指明该方法实现bean的初始化逻辑。
BeanDefinition的继承与实现关系
我们常用的
@Bean
,@Component
,bean标签
等都会解析为BeanDefinition对象,然后在通过BeanFactory去创建Bean。
部分源码
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
// 单例、原型标识符(其实远不止这两种)
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 标识 Bean 的类别,分别对应 用户定义的 Bean、来源于配置文件的 Bean、Spring 内部的 Bean
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// 设置、返回 Bean 的父类名称
void setParentName(@Nullable String parentName);
String getParentName();
// 设置、返回 Bean 的 className
void setBeanClassName(@Nullable String beanClassName);
String getBeanClassName();
// 设置、返回 Bean 的作用域
void setScope(@Nullable String scope);
String getScope();
// 设置、返回 Bean 是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置、返回当前 Bean 所依赖的其它 Bean 名称。
void setDependsOn(@Nullable String... dependsOn);
String[] getDependsOn();
// 设置、返回 Bean 是否可以自动注入。只对 @Autowired 注解有效
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// 设置、返回当前 Bean 是否为主要候选 Bean 。
// 当同一个接口有多个实现类时,通过该属性来配置某个 Bean 为主候选 Bean。
void setPrimary(boolean primary);
boolean isPrimary();
// 设置、返回创建该 Bean 的工厂类。
void setFactoryBeanName(@Nullable String factoryBeanName);
String getFactoryBeanName();
// 设置、返回创建该 Bean 的工厂方法
void setFactoryMethodName(@Nullable String factoryMethodName);
String getFactoryMethodName();
// 返回该 Bean 构造方法参数值、所有属性
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();
// 返回该 Bean 是否是单例、是否是非单例、是否是抽象的
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
// 返回 Bean 的类别。类别对应上面的三个属性值。
int getRole();
以上是关于spring核心之BeanDefinition的主要内容,如果未能解决你的问题,请参考以下文章
[死磕 Spring 14/43] --- IOC 之注册解析的 BeanDefinition
Spring核心之BeanFactory 一张图看懂getBean全过程.
Spring核心之BeanFactory 一张图看懂getBean全过程.