微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring中的BeanDefinition

BeanDeFinition描述

Javadoc

BeanDeFinition描述了一个bean的实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息;这只是一个最小的接口,它的主要目的是允许beanfactoryPostProcessor(例如PropertyPlaceholderConfigurer)内省和修改属性值和其他bean的元信息(元信息即BeanDeFinition);

 

BeanDeFinition接口的方法列表

方法列表上看,BeanDeFinition接口几乎将bean的所有类信息收集并封装起来,接口包含的信息主要为以下几个方面

  • Bean的类信息

  全限定类名(beanClassName)

  作用域(scope),是否认Bean(primary),描述信息(description)等

  • Bean的行为特征

  是否延迟加载(lazy),是否自动注入 ( autowireCandidate ) ,初始化 / 销毁方法 ( initMethod / destroyMethod ) 等

  • Bean与其他Bean之间的关系 

   父Bean名 ( parentName ) ,依赖的Bean ( dependsOn ) 等

   构造器参数 ( 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具有通用性;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方法创建);

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐