我们知道平时在开发中使用Spring的时候,都是将对象交由Spring去管理,那么将一个对象加入到Spring容器中,有哪些方式呢,下面我就来总结一下
1、@Configuration + @Bean这种方式其实,在上一篇文章已经介绍过了,也是我们最常用的一种方式,@Configuration用来声明一个配置类,然后使用 @Bean 注解,用于声明一个bean,将其加入到Spring容器中。具体代码如下:
123456789@Configurationpublic class MyConfiguration { @Bean public Person person() { Person person = new Person(); person.setName("spring"); return person; }}
2、@Componet + @ComponentScan这种方式也是我们用的比较多的方式,@Componet中文译为组件,放在类名上面,然后@Comp ...
前言在当下这个时代,我们每天都会借助浏览器浏览很多内容。但你是否有考虑过当你在浏览器中访问某一个网址时候,这背后都发生了那些事情呢?
事实上,当在浏览器中键入url后,其背后的处理逻辑可大致如下图所示:
![](../../images/Pictures/新建 Markdown/b88bb4a914424b7c88fd7abf9a76eea7_tplv-k3u1fbpfcp-jj-mark_3024_0_0_0_q75-1696584179853.awebp)
可以看到,键入url后其大致会经历如下几个步骤:
DNS解析: 首先,浏览器会解析网址中的主机名,以获取服务器的IP地址。这个过程通过DNS(域名系统)完成。
建立TCP连接: 一旦浏览器知道了服务器的IP地址,它会尝试建立到服务器的TCP连接。通常这个过程会包括三次握手,以确保客户端和服务器之间的连接建立成功。
发送HTTP请求: 一旦TCP连接建立,浏览器会发送一个Http请求到服务器。这个请求包括了要访问的资源路径、HTTP方法(GET、POST等)、请求头(包含用 ...
1 SPI的概念APIAPI在我们日常开发工作中是比较直观可以看到的,比如在 Spring 项目中,我们通常习惯在写 service 层代码前,添加一个接口层,对于 service 的调用一般也都是基于接口操作,通过依赖注入,可以使用接口实现类的实例。
简单形容就是这样的:
图1:API
如上图所示,服务调用方无需关心接口的定义与实现,只进行调用即可,接口、实现类都是由服务提供方提供。服务提供方提供的接口与其实现方法就可称为API,API中所定义的接口无论是在概念上还是具体实现,都更接近服务提供方(实现方),通常接口与实现类在同一包中;
SPI如果我们将接口的定义放在调用方,服务的调用方定义一个接口规范,可以由不同的服务提供者实现。并且,调用方能够通过某种机制来发现服务提供方,通过调用接口使用服务提供方提供的功能,这就是SPI的思想。
SPI 的全称是Service Provider Interface,字面意思就是服务提供者的接口,是由服务提供者定义的接口。
图2:SPI
服务提供方按接口规范实现服务,服务调用方通过某种机制为这个接口寻找到这个服务, SPI的特点很明显:接口 ...
1. 起因:
开发过程中,我发现项目里大量使用了@ManyToOne(fetch = FetchType.LAZY)注解,脑海中又联想到了@Lazy,觉得挺有意思记录一下
@ManyToOne(fetch = FetchType.LAZY)是Hibernate框架中的注解,它表示该属性是多对一关系,而且在查询时应该使用懒加载策略。懒加载是指只有在访问该属性时才会从数据库中加载相关数据。例如,如果一个实体类中有一个ManyToOne关联属性,如果没有使用懒加载策略,那么在查询该实体类时,该ManyToOne关联属性所关联的实体类也会被查询出来,这样就会增加不必要的查询开销和内存占用。而使用懒加载策略,只有在访问该ManyToOne关联属性时才会进行查询,从而提高查询效率和减少内存占用。
@Lazy是Spring框架中的注解,它可以用于标记Spring Bean的初始化方式。当使用 @Lazy 注解时,Spring容器会在第一次访问该Bean时才进行初始化,而不是在容器启动时就初始化。这样可以提高容器启动速度和减少内存占用。例如,如果一个应用程序中有很多Bean,如果这 ...
@Configuration 注解相信各位小伙伴经常会用到,但是大家知道吗,这个注解有两种不同的模式,一种叫做 Full 模式,另外一种则叫做 Lite 模式。
准确来说,Full 模式和 Lite 模式其实 Spring 容器在处理 Bean 时的两种不同行为。
这两种不同的模式在使用时候的表现完全不同,今天我们就来捋一捋这两种模式。
1. 概念梳理首先我们先来看一下 Spring 官方文档中对 Full 模式和 Lite 模式的一个介绍:
![](images/Pictures/@Configuration 注解的两种模式/640.png)
截图来自:https://docs.spring.io/spring-framework/reference/core/beans/java/basic-concepts.html
这个文档主要讲了这样几件事情:
我们可以通过在一个方法上添加 @Bean 注解,进而将该方法的返回值暴露给 Spring 容器,在这种场景下,**@Bean** 注解实际上就是一种通用的工厂方法机制。
当一个添加了 @Bean 注 ...
目录[TOC]
1、FineReport常用功能
大屏
传统报表
数据填报
数据随行(移动端)
权限划分
2、FineReport传统报表的开发流程
新建数据连接:比如说,你要连接数据库,连接数据库的哪一张表。
新建模板数据集:模板数据集只对当前文件生效,常用的。
设置表的模板样式:自定义模板样式,并绑定数据。
效果预览:完成上述操作后,可以进行效果预览,效果不好,我们调整后,再进行预览…
3、FineReport开发流程演示说明1)怎么查看firereport的工作环境
2)新建数据连接① 新建连接:完成下面的1,2,3,4步骤
② 数据库连接:完成下面的1,2,3,4,5,6步骤
3)创建数据集
模板数据集:只针对当前文件生效。
服务器数据集:对所有文件生效。
① 创建模板数据集
② 最终效果如下
4)模板样式设计:绑定数据eg:假如我们想要设计的模板样式如下:
① 按照图示步骤,完成1,2,3,4,5的操作
② 保存这个模板
5)模板预览① 点击如下按钮
② 效果如下:自动在浏览器中打开
4、扩展操作(很重要)
扩展操作分为:纵向扩展(默认)、横向扩展、不扩展。
1)连接 ...
经验教程
未读需求-问题
在生产中,由这样的一个需求:重新使用data中的数据,但是data中的数据已经被各种表单、变量等赋值,那么怎么重置data的值呢?
解决方案① 逐个赋值1234567891011121314151617...data() { return { name: '', sex: '', desc: '', ------省略------- }}...// 逐个赋值this.name = ''this.sex = ''this.desc = ''
很明显,这个方法比较笨,当然也可以实现效果,但是一个一个去重新赋值比较麻烦而且代码看起来也会比较乱。
那么,有如何做才能==更优雅==?
② 使用 Object.assign()
MDN关于该方法的介绍:Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。 ...
技术学习
未读前言本篇文章主要介绍基于Redis的分布式锁实现到底是怎么一回事,其中参考了许多大佬写的文章,算是对分布式锁做一个总结
分布式锁概览在多线程的环境下,为了保证一个代码块在同一时间只能由一个线程访问,Java中我们一般可以使用synchronized语法和ReetrantLock去保证,这实际上是本地锁的方式。但是现在公司都是流行分布式架构,在分布式环境下,如何保证不同节点的线程同步执行呢?
实际上,对于分布式场景,我们可以使用分布式锁,它是控制分布式系统之间互斥访问共享资源的一种方式。
比如说在一个分布式系统中,多台机器上部署了多个服务,当客户端一个用户发起一个数据插入请求时,如果没有分布式锁机制保证,那么那多台机器上的多个服务可能进行并发插入操作,导致数据重复插入,对于某些不允许有多余数据的业务来说,这就会造成问题。而分布式锁机制就是为了解决类似这类问题,保证多个服务之间互斥的访问共享资源,如果一个服务抢占了分布式锁,其他服务没获取到锁,就不进行后续操作。大致意思如下图所示(不一定准确):
分布式锁的特点分布式锁一般有如下的特点:
互斥性: 同一时刻只能有一个线程持有锁
可重入性 ...
技术学习
未读
使用Base64编码上传文件的一些原因:通用性:Base64编码的结果是ASCII字符串,这是一种通用的字符集,可以在几乎所有系统中被解析。兼容性:HTTP协议是文本协议,一些非ASCII字符在传输过程中可能出现问题。Base64编码将二进制数据转换成纯文本,避免了这个问题。数据封装:有时候,我们可能需要将文件和其他数据(如文本、JSON等)一起发送。Base64编码可以让我们把文件编码成字符串,并和其他数据一起发送。然而,使用Base64编码也有缺点:体积增大:Base64编码会使数据体积增大约33%,因为每3个字节的数据需要用4个字节的Base64字符来表示。CPU使用率:编码和解码Base64需要CPU资源,大量的Base64编码/解码可能会影响性能。
1. 前言最近在开发中遇到文件上传采用Base64的方式上传,记得以前刚开始学http上传文件的时候,都是通过content-type为multipart/form-data方式直接上传二进制文件,我们知道都通过网络传输最终只能传输二进制流,所以毫无疑问他们本质上都是一样的,那么为什么还要先转成Base64 ...
如何使用Builder模式创建线程池前言Builder 设计模式也叫做 构建者模式或者建造者模式,名字只是一种叫法,当聊起三种名称的时候知道是怎么回事就行。
Builder 设计模式在作者编码过程中,属于比较常用的模式之一。优秀的设计模式总是会受到广大开发者的青睐,Hutool 也是其中之一。
因为这周编写的业务需要用到线程池,就去 Hutool thread 包下看了看,还真有惊喜,学习到了一种之前编码中没用过的 Builder 模式实现。
这里必须提一句:设计模式重要的是思想,一种设计模式可能不止一种实现方式。
Builder 模式应用场景Builder 模式作用域:如果类的属性之间有一定的依赖关系或者约束条件(源自设计模式之美),那么就可以考虑使用 Builder 设计模式。
我们依照线程池来举例,默认创建的线程池,构造方法最多有七个参数,核心线程数、最大线程数、阻塞队列、线程存活时间…
日常使用创建线程池时,大家想一下为什么要这么设计?一起来看下源码注释中如何解释此行为。
线程池之所以设置如此之多的构造参数,是因为对这些参数会有一定规则的校验,如果不满足线程池的规则,将不允许 ...