Spring-依赖来源

2024-05-10 00:52
文章标签 java 来源 依赖 spring

本文主要是介绍Spring-依赖来源,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

依赖来源

1 Spring BeanDefinition(xml,注解,BeanDefinitionBuilder, 还有API实现的单例对象)
2 Spring 内建BeanDefinition
在这里插入图片描述
3 内建单例对象
在这里插入图片描述

依赖注入和依赖查找的区别

Context.refresh() 的时候会调用这个方法:prepareBeanFactory(beanFactory)注入下面这几个对象:
在这里插入图片描述
我们可以看到在依赖查找的时候用到了:

在这里插入图片描述

public class DependencySourceDemo {//  字段注入注入postProcessProperties 方法执行 早于setter注入 也早于 @PostConstruct@AutowiredBeanFactory beanFactory;@AutowiredResourceLoader resourceLoader;@AutowiredApplicationContext applicationContext;@AutowiredApplicationEventPublisher publisher;@PostConstructpublic void init() {System.out.println(beanFactory == applicationContext);System.out.println(beanFactory == applicationContext.getAutowireCapableBeanFactory());System.out.println(resourceLoader == applicationContext);System.out.println(publisher == applicationContext);}@PostConstructpublic void initLookUp() {getBean(BeanFactory.class);getBean(ApplicationEventPublisher.class);getBean(ApplicationContext.class);getBean(ResourceLoader.class);}public <T> T getBean(Class<T> type) {try {beanFactory.getBean(type);} catch (NoSuchBeanDefinitionException e) {System.err.println("无法在当前容器总找到" + type + "类型的bean");}return null;}public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(DependencySourceDemo.class);context.refresh();}
}

运行结果:
在这里插入图片描述
所以说依赖注入会比依赖查找多这样几个对象。

依赖来源及依赖使用场景

比较这几种来源的使用场景:
单体对象也就是内建的单例对象
在这里插入图片描述
1 Spirng BeanDefinition 通过 DefaultListableBeanFactory#registerBeanDefinition进行注册
这个方法后面会有这样一段代码,前者是存储了beanName和beanDefinition 后者是为了保证顺序,因为后者是一个ArrayList
在这里插入图片描述
2 单体对象
由SingletonBeanRegistry#registerSingleton
限制是没有生命周期管理的,也无法实现延迟初始化。
在这里插入图片描述
为什么ConcurrentHashMap还有加锁呢?
因为我们查找了以后如果没有还需要往里面放,所以也存在线程安全问题。
我们看到这里还有一把锁,是因为这个方法可能会被单独使用,但是其实这里锁的是同一个对象,如果是同一个线程内没有额外加锁。

在这里插入图片描述
同样这里也使用了LinkedHashSet保证了有序:
在这里插入图片描述

非容器托管的对象

DefaultListableBeanFactory#registerResolvableDependency
限制:
没有生命周期
无法实现延迟初始化
无法通过依赖查找

public class ResolvableDependencySourceDemo {
@Autowired
String value;
public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(ResolvableDependencySourceDemo.class);context.addBeanFactoryPostProcessor(beanFactory -> {beanFactory.registerResolvableDependency(String.class, "demo");});context.refresh();ResolvableDependencySourceDemo bean = context.getBean(ResolvableDependencySourceDemo.class);System.out.println(bean.value);
}
}

这里为什么要这样写呢?通过回调函数,因为我们依赖注入的时候如果容器启没有refresh beanFactory.registerResolvableDependency(String.class, “demo”);这个时候注册会报错,如果启动了,我们可不可以把这个注册写到refresh之后呢?不可以因为这个时候上面的@Autowired 注入的时候找不到这个bean也会报错,所以通过回调函数的方式来处理,当Factory创建好以后进行注册。

外部化配置作为依赖

没有生命周期
无法实现延迟初始化
无法通过依赖查找

@Configuration
@PropertySource(value = "meta-info/demo.properties", encoding = "GBK")
public class ExtDependencyDemo {@Value("${usr.name}")private String name;@Value("${usr.pass}")private String pass;public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(ExtDependencyDemo.class);context.refresh();ExtDependencyDemo bean = context.getBean(ExtDependencyDemo.class);System.out.println(bean.pass);System.out.println(bean.name);}
}

参考资料:小马哥核心编程思想

这篇关于Spring-依赖来源的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974975

相关文章

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

SpringBoot日志级别与日志分组详解

《SpringBoot日志级别与日志分组详解》文章介绍了日志级别(ALL至OFF)及其作用,说明SpringBoot默认日志级别为INFO,可通过application.properties调整全局或... 目录日志级别1、级别内容2、调整日志级别调整默认日志级别调整指定类的日志级别项目开发过程中,利用日志

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有