Loading

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

AbstractBeanDefinitionBeanDefinition接口的的抽象实现类,其中排除了GenericBeanDefinitionRootBeanDefinitionChildBeanDefinition的常用属性;自动装配常量与 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具有通用性;GenericBeanDefinitionAbstractBeanDefinition相比多了一个parentName的属性;使用此GenericBeanDefinition类来注册用户可见的BeanDefinition(后置处理器可对其进行操作,甚至可能重新配置parentName);其中,BeanDefinition的父/子关系是通过RootBeanDefinition/ChildBeanDefinition设置;

GenericBeanDefinition是AbstractBeanDefinition的非抽象扩展,它可以从父BeanDefinition继承一些属性信息;

 

RootBeanDefinition

RootBeanDefinition只能作为独立的BeanDefinition,或以父BeanDefinition的形式出现,不能继承其他BeanDefinition;

RootBeanDefinitionAbstractBeanDefinition上扩展了一些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 上的注解信息提供出来,它的子类有AnnotatedGenericBeanDefinitionScannedGenicBeanDefinition都是基于注解驱动下的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方法创建);

 

posted @ 2022-07-24 22:30  街头卖艺的肖邦  阅读(210)  评论(0编辑  收藏  举报