定义Bean对象有哪些方式?
在Spring容器中我们使用的一个一个的Bean,那我们定义Bean的形式有哪些呢?
<bean/>@Bean@Component/@Service/@Controller
除了上述方式我们还可以通过BeanDefinition这个类来定义Bean对象
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
// 生成一个BeanDefinition对象,并设置beanClass为UserService.class,并注册到ApplicationContext中
AbstractBeanDefinition beanDefinition =BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(UserService.class);
context.registerBeanDefinition("userService", beanDefinition);
System.out.println(context.getBean("userService"));
// 设置作用域
beanDefinition.setScope("prototype");
// 设置初始化方法
beanDefinition.setInitMethodName("init");
// 设置懒加载
beanDefinition.setLazyInit(true);
BeanDefinition
那么怎么理解BeanDefinition?
BeanDefinition是Bean在Spring中的描述,是Bean在Spring中的定义形态,有了BeanDefinition我们就可以创建Bean。BeanDefinition与Bean的关系可以理解为类与对象的关系,类在Spring的数据结构就是BeanDefinition,根据BeanDefinition得到的对象就是我们需要的Bean。
BeanDefinition中存在很多属性用来描述一个Bean的特点:
- class,表示Bean类型
- scope,表示Bean作用域,单例或原型等
- lazyInit:表示Bean是否是懒加载
- initMethodName:表示Bean初始化时要执行的方法
- destroyMethodName:表示Bean销毁时要执行的方法
- 还有很多...
BeanDefinition是一个接口,具体的接口内容如下:
package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/**
* A BeanDefinition describes a bean instance, which has property values,
* constructor argument values, and further information supplied by
* concrete implementations.
*
* <p>This is just a minimal interface: The main intention is to allow a
* {@link BeanFactoryPostProcessor} to introspect and modify property values
* and other bean metadata.
*
* @author Juergen Hoeller
* @author Rob Harrop
* @since 19.03.2004
* @see ConfigurableListableBeanFactory#getBeanDefinition
* @see org.springframework.beans.factory.support.RootBeanDefinition
* @see org.springframework.beans.factory.support.ChildBeanDefinition
*/
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
//标准单例作用域的作用域标识符:“singleton”。
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
//标准原型作用域的范围标识符:“prototype”
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// Bean角色
int ROLE_APPLICATION = 0; //用户自定义
int ROLE_SUPPORT = 1; //来源于配置文件
int ROLE_INFRASTRUCTURE = 2; //Spring内部的
//配置 /获取父BeanDefinition的名称 XML中的 <bean parent="">
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
//配置/获取 Bean 的 Class 全路径 XML 中的 <bean class="">
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
//配置/获取 Bean 的作用域 XML中的 <bean scope=""> 配置
void setScope(@Nullable String scope);
@Nullable
String getScope();
//配置 / 获取 Bean 是否懒加载(默认false,立马加载) XML 中的 <bean lazy-init="">
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
//配置/获取 Bean 的依赖对象 XML中的 <bean depends-on="">
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
//配置/获取 Bean 是否是自动装配的候选者 默认为 true XML中的 <bean autowire-candidate="">
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
//了多个可注入bean,那么则选择被Primary标记的bean/获取当前 Bean 是否为首选的 Bean XML中的 <bean primary="">
void setPrimary(boolean primary);
boolean isPrimary();
// 配置/获取 FactoryBean 的名字 XML中的<bean factory-bean="">
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
// FactoryMethod 的名字,可以是某个实例的方法(和factoryBean配合使用) //也可以是静态方法。 XML 中的<bean factory-method="">
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
//返回该 Bean 构造方法的参数值
ConstructorArgumentValues getConstructorArgumentValues();
//判断 getConstructorArgumentValues 是否是空对象。
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
//获取普通属性的集合
MutablePropertyValues getPropertyValues();
//判断 getPropertyValues 是否为空对象
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 配置/获取 Bean 的初始化方法 XML中的<bean init-method="">
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
// 配置/获取 Bean 的销毁方法 XML中的<bean destroy-method="">
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
/**
* //配置/获取 Bean的角色
* @see #ROLE_APPLICATION
* @see #ROLE_SUPPORT
* @see #ROLE_INFRASTRUCTURE
*/
void setRole(int role);
int getRole();
//配置/获取 Bean 的描述
void setDescription(@Nullable String description);
@Nullable
String getDescription();
// Read-only attributes
/**
* Return a resolvable type for this bean definition,
* based on the bean class or other specific metadata.
* <p>This is typically fully resolved on a runtime-merged bean definition
* but not necessarily on a configuration-time definition instance.
* @return the resolvable type (potentially {@link ResolvableType#NONE})
* @since 5.2
* @see ConfigurableBeanFactory#getMergedBeanDefinition
*/
ResolvableType getResolvableType();
//是否为单例
boolean isSingleton();
// 是否为原型
boolean isPrototype();
//是否抽象 XML 中的<bean abstract="true">
boolean isAbstract();
/**
* Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors).
*/
@Nullable
String getResourceDescription();
// 如果当前 BeanDefinition 是一个代理对象,那么该方法可以用来返回原始的 BeanDefinition
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
从上边的属性和方法来看,BeanDefinition对于一个Bean的描述做了较为完整的一套约束,这为后续的子类提供了最近本的职责和属性。而通过<bean/>,@Bean,@Component等声明式的方式所定义的Bean最终都会被Spring解析为对应的BeanDefinition对象,并放入Spring容器中。