ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring中的BeanDefinition

2022-07-24 22:33:41  阅读:122  来源: 互联网

标签:Spring Bean private bean 属性 public 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具有通用性;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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有