Spring中的BeanDefinition
作者:互联网
BeanDefinition描述
Javadoc
BeanDefinition描述了一个bean的实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息;这只是一个最小的接口,它的主要目的是允许BeanFactoryPostProcessor(例如PropertyPlaceholderConfigurer)内省和修改属性值和其他bean的元信息(元信息即BeanDefinition);
BeanDefinition接口的方法列表
从方法列表上看,BeanDefinition接口几乎将bean的所有类信息收集并封装起来,接口包含的信息主要为以下几个方面
- Bean的类信息
全限定类名(beanClassName)
- Bean的属性
作用域(scope),是否默认Bean(primary),描述信息(description)等
- Bean的行为特征
是否延迟加载(lazy),是否自动注入 ( autowireCandidate ) ,初始化 / 销毁方法 ( initMethod / destroyMethod ) 等
- Bean与其他Bean之间的关系
父Bean名 ( parentName ) ,依赖的Bean ( dependsOn ) 等
- Bean的配置属性
构造器参数 ( constructorArgumentValues ) ,属性变量值 ( propertyValues ) 等
BeanDefinition结构体系
AttributeAccessor
AttributeAccessor是属性的访问器,用于将元数据附加到任意对象,或从任意对象访问元数据的通用协定接口;
其中,AttributeAccessor不仅有getter和setter方法,它还有具备移除属性信息的remove方法;因此,BeanDefinition接口继承了AttributeAccessor接口,BeanDefinition接口具有访问,修改,移除bean属性的功能;
BeanMetadataElement
BeanMetadataElement的类名中有metadata,从类名可以看出,它存放了bean的元信息,这个接口只有一个方法,该方法是用于获取bean的资源来源(资源来源即bean的文件路径或URI路径);
AbstractBeanDefinition
AbstractBeanDefinition为BeanDefinition接口的的抽象实现类,其中排除了GenericBeanDefinition,RootBeanDefinition和ChildBeanDefinition的常用属性;自动装配常量与 AutowireCapableBeanFactory接口中定义的常量匹配;
针对不同的BeanDefinition的实现,需要一些特殊的属性,因此抽象出一个父类用于存放通用的属性;
AbstractBeanDefinition里面定义了一些比较重要的属性
查看代码
// bean的全限定类名
private volatile Object beanClass;
// 默认的作用域为单实例
private String scope = SCOPE_DEFAULT;
// 默认bean都不是抽象的
private boolean abstractFlag = false;
// 是否延迟初始化
private Boolean lazyInit;
// 自动注入模式(默认不自动注入)
private int autowireMode = AUTOWIRE_NO;
// 是否参与IOC容器的自动注入(设置为false则它不会注入到其他bean,但其他bean可以注入到它本身)
private boolean autowireCandidate = true;
// 同类型的首选bean
private boolean primary = false;
// bean的构造器参数和参数值列表
private ConstructorArgumentValues constructorArgumentValues;
// bean的属性和属性值集合
private MutablePropertyValues propertyValues;
// bean的初始化方法
private String initMethodName;
// bean的销毁方法
private String destroyMethodName;
// bean的资源来源
private Resource resource;
其中,上面的autowireMode属性有5种选择,AUTOWIRE_NO(不自动注入),AUTOWIRE_BY_NAME(根据bean的名称注入),AUTOWIRE_BY_TYPE(根据bean的类型注入),AUTOWIRE_CONSTRUCTOR(根据bean的构造器注入),AUTOWIRE_AUTODETECT(借助内省决定如何注入,3.0标记弃用),AUTOWIRE_NO为默认属性;
GenericBeanDefinition
Generic意思是通用,一般的,因此GenericBeanDefinition具有通用性;GenericBeanDefinition与AbstractBeanDefinition相比多了一个parentName的属性;使用此GenericBeanDefinition类来注册用户可见的BeanDefinition(后置处理器可对其进行操作,甚至可能重新配置parentName);其中,BeanDefinition的父/子关系是通过RootBeanDefinition/ChildBeanDefinition设置;
GenericBeanDefinition是AbstractBeanDefinition的非抽象扩展,它可以从父BeanDefinition继承一些属性信息;
RootBeanDefinition
RootBeanDefinition只能作为独立的BeanDefinition,或以父BeanDefinition的形式出现,不能继承其他BeanDefinition;
RootBeanDefinition在AbstractBeanDefinition上扩展了一些bean的信息
- bean的id和别名
- bean的注解信息
- bean的工厂相关信息(是否为工厂bean,工厂类,工厂方法等)
查看代码
// BeanDefinition的引用持有,存放了Bean的别名
private BeanDefinitionHolder decoratedDefinition;
// Bean上面的注解信息
private AnnotatedElement qualifiedElement;
// Bean中的泛型
volatile ResolvableType targetType;
// BeanDefinition对应的真实的Bean
volatile Class<?> resolvedTargetType;
// 是否是FactoryBean
volatile Boolean isFactoryBean;
// 工厂Bean方法返回的类型
volatile ResolvableType factoryMethodReturnType;
// 工厂Bean对应的方法引用
volatile Method factoryMethodToIntrospect;
ChildBeanDefinition
ChildBeanDefinition与GenericBeanDefinition一样都是集成了一个parentName属性来作为父BeanDefinition的指向,不同的是,ChildBeanDefinition没有默认的无参构造器,必须要传入parentName才可以,但GenericBeanDefinition有两种不同的构造器;
AnnotatedBeanDefinition
AnnotatedBeanDefinition不是BeanDefinition的实现类,而是一个子接口;
AnnotatedBeanDefinition可以把 Bean 上的注解信息提供出来,它的子类有AnnotatedGenericBeanDefinition和ScannedGenicBeanDefinition,都是基于注解驱动下的Bean的注册,封装BeanDefinition;
BeanDefinition的获取
ConfigurableListBeanFactory#getBeanDefintion获取BeanDefinitioin,其中ConfigurableListBeanFactory具备可配置和可列举的特性,ConfigurableListBeanFactory的默认实现类为DefaultListableBeanFactory;
基于XML的BeanDefinition
查看代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="org.example.bean.Person">
<property name="name" value="test"/>
</bean>
</beans>
查看代码
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
查看代码
public class BeanDefinitionTest {
public static void main(String[] args) throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
BeanDefinition personBeanDefinition = ctx.getBeanFactory().getBeanDefinition("person");
System.out.println(personBeanDefinition);
}
}
执行结果:
Generic bean: class [org.example.bean.Person]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [bean.xml]
它的BeanDefinition是Generic bean类型;
基于@Component的BeanDefinition
查看代码
@Component
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
查看代码
public class BeanDefinitionTest {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.registerBean(Person.class);
ctx.refresh();
BeanDefinition personBeanDefinition = ctx.getBeanFactory().getBeanDefinition("person");
System.out.println(personBeanDefinition);
}
}
执行结果:
Generic bean: class [org.example.bean.Person]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
基于XML的BeanDefinition与基于@Component的BeanDefinition的加载来源不同的是:基于XML解析出来的bean,定义来源是XML配置文件;基于@Component注解解析出来的bean,定义来源是类的字节码文件中;
基于@Bean的BeanDefinition
查看代码
@Configuration
public class BeanDefinitionConfiguration {
@Bean
public Person person() {
return new Person();
}
}
查看代码
public class BeanDefinitionTest {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(BeanDefinitionConfiguration.class);
ctx.refresh();
BeanDefinition personBeanDefinition = ctx.getBeanFactory().getBeanDefinition("person");
System.out.println(personBeanDefinition);
}
}
执行结果:
Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=beanDefinitionConfiguration; factoryMethodName=person; initMethodName=null; destroyMethodName=(inferred); defined in org.example.bean.BeanDefinitionConfiguration
@Bean类型的BeanDefinition为Root bean(ConfigurationClassBeanDefinition继承自RootBeanDefinition),属性中c移除了className,自动注入模式为构造器注入,添加了factoryBean的属性(person由beanDefinitionConfiguration的person方法创建);
标签:Spring,Bean,private,bean,属性,public,BeanDefinition 来源: https://www.cnblogs.com/coder-zyc/p/16489062.html