Spring 5.x 源码之旅二BeanDefinition预备知识

Bean定义

后面我们频繁的会跟bean定义打交道,所以我们先要知道什么是bean定义,定义了什么呢,如果不了解这个,后面看下去一头雾水,很多东西怎么得来的不清楚,所以还是要先有个了解,我把相关的一些借口和类先介绍下。

BeanMetadataElement元数据接口

首先我们要能获得源数据,也就是这个bean是来自哪个对象的,我们就可以获得一些相关的信息。

public interface BeanMetadataElement {

	@Nullable
	default Object getSource() {
		return null;
	}

}

BeanMetadataAttribute元数据属性

在这里插入图片描述
实现了元数据接口,增加了属性的名字和值。

public class BeanMetadataAttribute implements BeanMetadataElement {
	//属性名字
	private final String name;
	//属性值
	@Nullable
	private final Object value;
	//bean的来源
	@Nullable
	private Object source;


	//将名字和值封装起来
	public BeanMetadataAttribute(String name, @Nullable Object value) {
		Assert.notNull(name, "Name must not be null");
		this.name = name;
		this.value = value;
	}



	public String getName() {
		return this.name;
	}


	@Nullable
	public Object getValue() {
		return this.value;
	}

	
	public void setSource(@Nullable Object source) {
		this.source = source;
	}

	@Override
	@Nullable
	public Object getSource() {
		return this.source;
	}


	@Override
	public boolean equals(@Nullable Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof BeanMetadataAttribute)) {
			return false;
		}
		BeanMetadataAttribute otherMa = (BeanMetadataAttribute) other;
		return (this.name.equals(otherMa.name) &&
				ObjectUtils.nullSafeEquals(this.value, otherMa.value) &&
				ObjectUtils.nullSafeEquals(this.source, otherMa.source));
	}

	@Override
	public int hashCode() {
		return this.name.hashCode() * 29 + ObjectUtils.nullSafeHashCode(this.value);
	}

	@Override
	public String toString() {
		return "metadata attribute '" + this.name + "'";
	}

}

AttributeAccessor属性访问器

这个就是定义了属性的操作接口,增删改查,获取所有的。

public interface AttributeAccessor {

	void setAttribute(String name, @Nullable Object value);

	@Nullable
	Object getAttribute(String name);

	@Nullable
	Object removeAttribute(String name);

	boolean hasAttribute(String name);

	String[] attributeNames();

}

AttributeAccessorSupport属性访问抽象实现类

在这里插入图片描述
这个是对AttributeAccessor接口的抽象实现,定义了一个map来存放名字和属性的映射关系。

public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {

	//名字和属性的对应
	private final Map<String, Object> attributes = new LinkedHashMap<>();

	//设置null就会删除
	@Override
	public void setAttribute(String name, @Nullable Object value) {
		Assert.notNull(name, "Name must not be null");
		if (value != null) {
			this.attributes.put(name, value);
		}
		else {
			removeAttribute(name);
		}
	}

	@Override
	@Nullable
	public Object getAttribute(String name) {
		Assert.notNull(name, "Name must not be null");
		return this.attributes.get(name);
	}

	@Override
	@Nullable
	public Object removeAttribute(String name) {
		Assert.notNull(name, "Name must not be null");
		return this.attributes.remove(name);
	}

	@Override
	public boolean hasAttribute(String name) {
		Assert.notNull(name, "Name must not be null");
		return this.attributes.containsKey(name);
	}

	@Override
	public String[] attributeNames() {
		return StringUtils.toStringArray(this.attributes.keySet());
	}


	//属性的复制
	protected void copyAttributesFrom(AttributeAccessor source) {
		Assert.notNull(source, "Source must not be null");
		String[] attributeNames = source.attributeNames();
		for (String attributeName : attributeNames) {
			setAttribute(attributeName, source.getAttribute(attributeName));
		}
	}

	//得同一个属性对象,或者每一个属性都相同
	@Override
	public boolean equals(@Nullable Object other) {
		return (this == other || (other instanceof AttributeAccessorSupport &&
				this.attributes.equals(((AttributeAccessorSupport) other).attributes)));
	}
	//map的hashCode
	@Override
	public int hashCode() {
		return this.attributes.hashCode();
	}

}

BeanMetadataAttributeAccessor元数据属性访问器

在这里插入图片描述
既能获取源数据,也能提供属性访问:

@SuppressWarnings("serial")
public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
	//bean的源数据对象
	@Nullable
	private Object source;

	
	public void setSource(@Nullable Object source) {
		this.source = source;
	}

	@Override
	@Nullable
	public Object getSource() {
		return this.source;
	}
	//添加进来的就是BeanMetadataAttribute 
	public void addMetadataAttribute(BeanMetadataAttribute attribute) {
		super.setAttribute(attribute.getName(), attribute);
	}

	//获得之后都会转成BeanMetadataAttribute
	@Nullable
	public BeanMetadataAttribute getMetadataAttribute(String name) {
		return (BeanMetadataAttribute) super.getAttribute(name);
	}
	//封装成BeanMetadataAttribute
	@Override
	public void setAttribute(String name, @Nullable Object value) {
		super.setAttribute(name, new BeanMetadataAttribute(name, value));
	}

	@Override
	@Nullable
	public Object getAttribute(String name) {
		BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.getAttribute(name);
		return (attribute != null ? attribute.getValue() : null);
	}

	@Override
	@Nullable
	public Object removeAttribute(String name) {
		BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.removeAttribute(name);
		return (attribute != null ? attribute.getValue() : null);
	}

}

BeanDefinition

我们的bean定义接口就是继承他们的,也就是说,我们的bean定义得有来源BeanMetadataElement,得可以操作AttributeAccessor。比如我给你一个类,你要将他转换成bean,你到知道他的一些信息吧,不然等于什么都没有,别说获取注解什么的了,当然同时可能这些信息不够,所以要扩展,可以设置任务属性,只要是我需要的。我想springbean定义的意图也差不多吧。
在这里插入图片描述

主要方法

代码就不贴了,说一些熟悉方法,其他还有很多,要看的时候可以切过去看:

//单例字符串singleton
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

//原型字符串prototype
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

//设置bean类名字,这个可能会在后置处理器中修改,比如用了GCLIB代理配置类的时候就会改
void setBeanClassName(@Nullable String beanClassName);

//设置范围,是单例,还是原型
void setScope(@Nullable String scope);

//设置是否是懒加载
void setLazyInit(boolean lazyInit);

//设置需要先加载的依赖的类名字数组
void setDependsOn(@Nullable String... dependsOn);

//设置是否适合给其他类做自动装配
void setAutowireCandidate(boolean autowireCandidate);

//设置是否优先自动装配
void setPrimary(boolean primary);

//设置FactoryBean的名字
void setFactoryBeanName(@Nullable String factoryBeanName);

//获取构造函数的参数
ConstructorArgumentValues getConstructorArgumentValues();

//设置初始化方法 对应@PostConstruct
void setInitMethodName(@Nullable String initMethodName);

//设置销毁时候的方法 对应@PreDestroy
void setDestroyMethodName(@Nullable String destroyMethodName);

可以看到,我们的bean定义是一步步来的,首先是定义这个bean的来源,然后是一些属性操作,然后是将两部分合起来作为bean定义的父接口,在这个基础上,再定义其他的一些操作。这样数据和操作接口分离,做到了很好的解耦和扩展。

好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识。   第2章:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。   第3章:讲解Spring IoC容器的知识,通过具体的实例详细地讲解IoC概念。同时,对Spring框架的三个最重要的框架级接口进行了剖析,并对Bean的生命周期进行讲解。   第4章:讲解如何在Spring配置文件中使用Spring 3.0的Schema格式配置Bean的内容,并对各个配置项的意义进行了深入的说明。   第5章:对Spring容器进行解构,从内部探究Spring容器的体系结构和运行流程。此外,我们还将对Spring容器一些高级主题进行深入的阐述。   第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。   第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、使用注解进行配置等内容。   第8章:介绍了Spring所提供的DAO封装层,这包括Spring DAO的异常体系、数据访问模板等内容。   第9章:介绍了Spring事务管理的工作机制,通过XML、注解等方式进行事务管理配置,同时还讲解了JTA事务配置知识。   第10章:对实际应用中Spring事务管理各种疑难问题进行透彻的剖析,让读者对Spring事务管理不再有云遮雾罩的感觉。   第11章:讲解了如何使用Spring JDBC进行数据访问操作,我们还重点讲述了LOB字段处理、主键产生和获取等难点知识。   第12章:讲解了如何在Spring中集成Hibernate、myBatis等数据访问框架,同时,读者还将学习到ORM框架的混用和DAO层设计的知识。   第13章:本章重点对在Spring中如何使用Quartz进行任务调度进行了讲解,同时还涉及了使用JDK Timer和JDK 5.0执行器的知识。   第14章:介绍Spring 3.0新增的OXM模块,同时对XML技术进行了整体的了解。   第15章:对Spring MVC框架进行详细介绍,对REST风格编程方式进行重点讲解,同时还对Spring 3.0的校验和格式化框架如果和Spring MVC整合进行讲解。   第16章:有别于一般书籍的单元测试内容,本书以当前最具实战的JUnit4+Unitils+ Mockito复合测试框架对如何测试数据库、Web的应用进行了深入的讲解。   第17章:以一个实际的项目为蓝本,带领读者从项目需求分析、项目设计、代码开发、单元测试直到应用部署经历整个实际项目的整体开发过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值