Java DefaultListableBeanFactory接口超详细介绍

目录
  • 前言
  • AliasRegistry
  • SimpleAliasRegistry
  • SingletonBeanRegistry
  • DefaultSingletonBeanRegistry
  • FactoryBeanRegistrySupport
  • AbstractBeanFactory
  • AbstractAutowireCapableBeanFactory
    • BeanDefinitionRegistry
    • ConfigurableListableBeanFactory

前言

本文,对bean工厂的接口做分析梳理具体实现不研究

默认的工厂实现为DefaultListableBeanFactory

类图

AliasRegistry

功能是实现对一个bean注册多个不同的别名

例如

@Component
public class AliasConfiguration implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerAlias("originalBeanName", "newAlias");
        beanFactory.registerAlias("originalBeanName", "newAlias2");
        beanFactory.registerAlias("otherOriginalBeanName", "newAlias3");
    }
}

接口

public interface AliasRegistry {
	void registerAlias(String name, String alias);
	void removeAlias(String alias);
	boolean isAlias(String name);
	String[] getAliases(String name);
}

AliasRegistry接口是alias注册管理接口,支持4个api,分别是注册alias、删除alias、获取alias、判断指定名称是否是alias。AliasRegistry该接口层次在spring中非常高,因而是非常基础的一个接口。继承此接口需要实现别名

SimpleAliasRegistry

@Override
	public void registerAlias(String name, String alias) {
		Assert.hasText(name, "'name' must not be empty");
		Assert.hasText(alias, "'alias' must not be empty");
		synchronized (this.aliasMap) {
			if (alias.equals(name)) {
				this.aliasMap.remove(alias);
				if (logger.isDebugEnabled()) {
					logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
				}
			}
			else {
				String registeredName = this.aliasMap.get(alias);
				if (registeredName != null) {
					if (registeredName.equals(name)) {
						// An existing alias - no need to re-register
						return;
					}
					if (!allowAliasOverriding()) {
						throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
								name + "': It is already registered for name '" + registeredName + "'.");
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
								registeredName + "' with new target name '" + name + "'");
					}
				}
				checkForAliasCircle(name, alias);
				this.aliasMap.put(alias, name);
				if (logger.isTraceEnabled()) {
					logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
				}
			}
		}
	}

SimpleAliasRegistry中维护aliasMap

如果存在重名,判断是否允许覆盖

判断循环引用,如果存在 alias, name和name, alias同时存在,抛出Circular reference异常

SingletonBeanRegistry

public interface SingletonBeanRegistry {
	void registerSingleton(String beanName, Object singletonObject);
	@Nullable
	Object getSingleton(String beanName);
	boolean containsSingleton(String beanName);
	String[] getSingletonNames();
	int getSingletonCount();
	Object getSingletonMutex();
}

注册获取单例接口具体实现

实现类

DefaultSingletonBeanRegistry

先看大名鼎鼎的三级缓存

        /*存放已经完成创建的bean  */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	/** 存放存放生成bean的工厂,生成bean后先放入earlySingletonObjects */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    /*存放提前暴露的bean实例,还未完全初始化*/
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

注册单例接口

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton

@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			addSingleton(beanName, singletonObject);
		}
	}
protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

如果直接把生成好的实例,那么直接放入singletonObjects中,并且name放入registeredSingletons

如果需要提交暴露

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

三级缓存发挥作用

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

分别尝试从singletonObjects和earlySingletonObjects中获取实例

如都获取不到锁住singletonObjects再次读一遍,如果没有其他线程修改,通过singletonFactory生成对象,放入

earlySingletonObjects并从singletonFactories中移除

FactoryBeanRegistrySupport

提供对factoryBean接口的支持。

FactoryBean是什么?

FactoryBean接口的作用在bean工工厂上。是对bean进行自定义实例化,可以认为是方法工厂模式。spring默认的工厂,生产所有的实例的方式都相同,而FactoryBean.getObject可以自定义这个方式

FactoryBean

public interface FactoryBean<T> {
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
	@Nullable
	T getObject() throws Exception;
	@Nullable
	Class<?> getObjectType();
	default boolean isSingleton() {
		return true;
	}
}

关键方法,调用FactoryBean的getObject生成bean实例

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
		Object object;
    ······················
		object = factory.getObject();
	·····················
		return object;
	}

AbstractBeanFactory

来到AbstractBeanFactory。基本没有扩展新的功能接口,这个类的主要对继承的接口有了个大概的实现,整个工厂大部分实现都在这里

AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory在AbstractBeanFactory的基础上又扩展了,Autowire功能

这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。

AutowireCapableBeanFactory的具体实现都在AbstractAutowireCapableBeanFactory

例如org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowire进行bean的注入

BeanDefinitionRegistry

BeanDefinition的一些操作接口

public interface BeanDefinitionRegistry extends AliasRegistry {
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	boolean containsBeanDefinition(String beanName);
	String[] getBeanDefinitionNames();
	int getBeanDefinitionCount();
	boolean isBeanNameInUse(String beanName);
}

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory具体:

1、2个忽略自动装配的的方法。

2、1个注册一个可分解依赖的方法。

3、1个判断指定的Bean是否有资格作为自动装配的候选者的方法。

4、1个根据指定bean名,返回注册的Bean定义的方法。

5、2个冻结所有的Bean配置相关的方法。

6、1个使所有的非延迟加载的单例类都实例化的方法(preInstantiateSingletons)。

总结:工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,扩展之后,加上自有的这8个方法,这个工厂接口总共有83个方法,实在是巨大到不行了。这个工厂接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法。

到此这篇关于Java DefaultListableBeanFactory接口超详细介绍的文章就介绍到这了,更多相关Java DefaultListableBeanFactory内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java ServletContext与ServletConfig接口使用教程

    目录 ServletContext接口 1.概念 2.功能 1.获取Web应用程序的初始化参数 2.实现多个Servlet对象共享数据 3.读取Web应用下的资源文件 ServletConfig接口 1.概念 2.ServletConfig的常用方法 ServletContext接口 1.概念 当Servlet容器启动时,会为每个Web应用创建一个唯一的ServletContext对象代表当前Web应用,可以和程序的容器(服务器)来通信. 两种获取方式: 通过request对象获取 Servle

  • Java 内置接口 Serializable示例详解

    目录 引言 Serializable 接口 Serializable 是一个标记型接口 serializable Version UID Java 序列化与JSON序列化的区别 Java序列化相较于 JSON 的优势 Java 类对象的序列化代码演示 总结 引言 上一部分我们着重讲了 Java 集合框架中在开发项目时经常会被用到的数据容器,在讲解.演示使用实践的同时,把这个过程中遇到的各种相关知识点:泛型.Lambada.Stream 操作,一并给大家做了梳理. 从这篇开始我们进入下一部分,用三

  • java中如何使用HttpClient调用接口

    目录 java使用HttpClient调用接口 HttpClient 提供的主要的功能 直接言归正传了!!!!上代码 java的HttpClient调用远程接口 使用方法 实例 java使用HttpClient调用接口 HttpClient 提供的主要的功能 (1)实现了所有 HTTP 的方法(GET,POST,PUT,DELETE 等) (2)支持自动转向 (3)支持 HTTPS 协议 (4)支持代理服务器等 直接言归正传了!!!!上代码 public static String sendPu

  • Java Map接口概述和常用方法详解

    目录 概述 Map常用子类 Map接口中的常用方法 Map集合遍历键找值方式 Entry键值对对象 Map集合遍历键值对方式 概述 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种一一对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对象,即java.util.Map接口. 我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图. Collection中的

  • Java基础学习之接口详解

    目录 概述 定义格式 含有抽象方法 含有默认方法和静态方法 含有私有方法和私有静态方法 基本的实现 实现的概述 抽象方法的使用 默认方法的使用 静态方法的使用 私有方法的使用 接口的多实现 抽象方法 默认方法 静态方法 优先级的问题 接口的多继承 其他成员特点 概述 接口,是Java语言中一种引用类型,是方法的集合,如果说类的内部封装了成员变量.构造方法和成员方法,那么接口的内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9). 接

  • Java如何实现http接口参数和返回值加密

    目录 参数和返回值得加密目的 具体实现方式 大致思路 代码实现 身份检验 参数和返回值得加密目的 为了保证接口不被人拦截下来恶意请求,保证程序的稳定性,我们可以使用接口加密的方法来保证参数和返回值的保密性. 具体实现方式 因为本人是写Java 的,所以这里就直接以Java代码为例.思想都是一样的,只是不同的语言都不同的实现方式. 大致思路 我们的参数和返回值只需要定义两个参数:ak,ct,ak存放堆成加密的秘钥,ct存放加密之后的请求内容. 加密方式用到AES对称加密和RSA非对称加密,将请求参

  • Java中的Comparable和Comparator接口

    目录 一. Comparable接口 1. Comparable简介 2. 为什么要实现Comparable接口 3. Comparable的实际应用 二. Comparator接口 1. Comparator简介 2. Comparator接口的实际运用 三. Comparable和Comparator的比较 一. Comparable接口 1. Comparable简介 Comparable是排序接口. 若一个类实现了Comparable接口,就意味着该类支持排序. 实现了Comparabl

  • Java BeanDefination接口详细讲解

    目录 功能作用 为什么这样设计 假设没有BeanDefinition 有BeanDefinition BeanDefinition 属性介绍 示例 功能作用 BeanDefinition 是定义 Bean 的配置元信息接口,包含: Bean 的类名 设置父 bean 名称.是否为 primary. Bean 行为配置信息,作用域.自动绑定模式.生命周期回调.延迟加载.初始方法.销毁方法等 Bean 之间的依赖设置,dependencies 构造参数.属性设置 BeanDefinition 子类方

  • Java DefaultListableBeanFactory接口超详细介绍

    目录 前言 AliasRegistry SimpleAliasRegistry SingletonBeanRegistry DefaultSingletonBeanRegistry FactoryBeanRegistrySupport AbstractBeanFactory AbstractAutowireCapableBeanFactory BeanDefinitionRegistry ConfigurableListableBeanFactory 前言 本文,对bean工厂的接口做分析梳理具

  • Java Lambda表达式超详细介绍

    目录 一.背景 1.Lambda表达式的语法 2.函数式接口 二.Lambda表达式的基本使用 三.语法精简 四.变量捕获 五.Lambda在集合当中的使用 1.Collection接口 六.List接口 1.sort()方法的演示 七.Map接口 一.背景 Lambda表达式是Java SE 8中一个重要的新特性.lambda表达式允许你通过表达式来代替功能接口. lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块). L

  • Java超详细介绍抽象类与接口的使用

    目录 1.抽象类的语法和特性 1.1语法 1.2特性 2.接口的语法和使用 2.1语法 2.2特性 1.抽象类的语法和特性 1.1语法 1.在Java中,一个类如果被abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体. // 抽象类:被abstract修饰的类 public abstract class Shape { // 抽象方法:被abstract修饰的方法,没有方法体 abstract public void draw()

  • Java迭代器与Collection接口超详细讲解

    目录 关于迭代器你都知道什么? 什么是迭代器? 迭代器的4个API 如何使用迭代器? Collection集合接口知多少? 为什么不使用数组而是集合? Collection接口的API都有什么? AbstractCollection类知多少? 关于迭代器你都知道什么? 什么是迭代器?   所谓迭代的意思就是交换替代,迭代器并不是一种数据结构或者集合,而是可以过迭代器中的方法逐个访问集合中的每个元素的一种方法.提到迭代器最重要的就是Iterator接口,所有想要使用迭代器迭代的结构都需要实现或者继

  • Java超详细介绍封装与访问控制修符

    概念:我们在写入一个类的时候,为了保护里边的属性不被随意的调用这是我们可以使用特殊的修饰符进行相应的保护,而这样的话我们似乎只能在该类中调用使用了,出现某些特殊情况时就会无法发调用,虽然挺高了安全性但也降低了灵活性,这个时候我们的包装类就出现了,我们通过对某个方法的进行特殊方法的包装来对其进行相应的调用与赋值.就相当于银行为了保护财产会选择将金钱放进保险柜中来确保其的安全,但是当我们要取钱时,银行就要拿钥匙打开保险柜.修饰符相当于银行的保险柜,封装相当于保险柜的钥匙. 访问修饰符如下: 1) p

  • Java集合框架超详细小结

    目录 一:Collection集合 1.1集合概述: 1.2集合架构 1.3Collection集合常用方法 二:迭代器Iterator 2.1Iterator接口 2.2Iterator的实现原理: 2.3增强for() 2.4迭代器注意事项 三:泛型 3.1泛型概述 3.2泛型的优缺点 3.3泛型的定义与使用 泛型方法 泛型接口 3.4泛型的通配符 通配符高级使用-----受限泛型 四:Java常见数据结构 4.1栈 4.2队列 4.3数组 4.4链表 4.5红黑树 五:List集合体系 5

  • SpringMVC超详细介绍自定义拦截器

    目录 1.什么是拦截器 2.自定义拦截器执行流程图 3.自定义拦截器应用实例 1.快速入门 2.注意事项和细节 3.Debug执行流程 4.多个拦截器 1.多个拦截器执行流程示意图 2.应用实例 3.主要事项和细节 1.什么是拦截器 说明 Spring MVC 也可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能. 自定义的拦截器必须实现 HandlerInterceptor 接口 自定义拦截器的三个方法 preHandle():这个方法在业务处理器处理请求之前被调用,在该方

  • Java类加载基本过程详细介绍

    Java类加载基本过程详细介绍 基本过程: 根据类的全限定名称加载定义类的二进制字节流. 将字节流代表的静态存储结构转化为方法区的运行时数据结构 内存中生成一个代表这个类的java.lang.Class对象,作为方法去这个类的各种数据访问入口 数组类本身不通过类加载器创建,由java虚拟机直接创建,数组类的元素类型由类加载器加载. 数组类的元素类型:数组去掉所有维度后的类型, 文件格式验证: 0xCAFEBABY 魔数开头: 主次版本号当前虚拟机可处理: 常量类型: 索引执行类型: utf8编码

  • java 注解的基础详细介绍

    java 注解的基础详细介绍 前言 注解是Java引入的一项非常受欢迎的补充,它提供了一种结构化的,并且具有类型检查能力的新途径,从而使得程序员能够为代码加入元数据,而不会导致代码杂乱且难以阅读.使用注解能够帮助我们避免编写累赘的部署描述文件,以及其他生成的文件. 注解的语法比较简单,除了@符号的使用之外,它基本与java固有的语法一致.但由于java源码中提供的内置注解很少,所以大部分同学对注解都不是很了解,虽然我们都接触过,比如java内置的几种注解: @Override,表示当前的方法定义

  • OneinStack一键安装PHP/JAVA/HHVM和超详细的VPS手动安装LNMP的方法

    继著名的LAMP Stack(Linux + Apache + MySQL/MariaDB + PHP)网站环境之后,LNMP Stack(Linux + Nginx + MySQL/MariaDB + PHP)以其负载小.静态文件处理能力强的优势,在Linux平台上开始流行,尤其是在配置不太高的VPS上应用广泛. 说起LNMP,多数人应该知道lnmp.org站长开发的LNMP一键安装包,该脚本虚拟主机管理.FTP用户管理.Nginx.MySQL/MariaDB.PHP的升级.常用缓存组件的安装

随机推荐