spring5-配外部文件-spEL-工厂bean-FactoryBean-注解配bean

spring配外部文件

我们先在Spring里配置一个数据源

1.导c3p0包,这里我们先学一下hibernate持久化框架,以后用mybites.

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.2.17.Final</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-c3p0</artifactId><version>5.3.0.Final</version></dependency>

2.安装mysql 8.x数据库(参考相关资料),导入驱动包

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.16</version></dependency>

3.看具体代码:

    <!-- 配置c3p0,ComboPooledDataSource对象,它指向一个数据源 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="root"></property><property name="password" value="xiong"></property><property name="jdbcUrl" value="jdbc:mysql://124.220.60.104:3306/spring5"></property><property name="driverClass" value="com.mysql.cj.jdbc.Driver"></property></bean>

测试数据库连接

	@Testpublic void dataSourcetest() throws SQLException{ApplicationContext ct = new ClassPathXmlApplicationContext("dataSource.xml");DataSource dataSource = (DataSource)ct.getBean("dataSource");System.out.println(dataSource.getConnection());}
-----------------------------------------------------------------
com.mchange.v2.c3p0.impl.NewProxyConnection@45c7e403 [wrapping: com.mysql.cj.jdbc.ConnectionImpl@2925bf5b]   //连接成功,产生一个代理数据库服务器

              上面这样配置,写死了数据是相对以后转生产环境中修改是十分不方便的,生产环境中,我们极有可能会把dao层打jar包,又分成多模块开发,所以修改起来是十分麻烦,所以我们会把值写成键值对的形式单独保存到一个文件中

使用外部文件保存数据值,再配spring配置文件

在这里插入图片描述
jdbc.properties

jdbc.user=root
jdbc.password=xiong
jdbc.url=jdbc:mysql://124.220.60.104:3306/spring5
jdbc.driverClass=com.mysql.cj.jdbc.Driver

dataSouce.xml–spring配置文件

    <!-- 配置c3p0,ComboPooledDataSource对象,它指向一个数据源 --><context:property-placeholder location="classpath:jdbc.properties"/><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="user" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property><property name="jdbcUrl" value="${jdbc.url}"></property><property name="driverClass" value="${jdbc.driverClass}"></property></bean>

Spring的表达式语言spEL

       Spring表达式语言(SpEL):是一个支持运行时查询和操作对象图的强大表示是语言,是一种可以与一个基于spring的应用程序中的运行时对象交互的东西。总得来说SpEL表达式是一种简化开发的表达式,通过使用表达式来简化开发,减少一些逻辑、配置的编写。

       语法类似于 EL:SpEL 使用 #{…} 作为定界符 , 所有在大括号中的字符都将被认为是 SpEL , SpEL 为 bean 的属性进行动态赋值提供了便利。
通过 SpEL 可以实现:

通过 bean 的 id 对 bean 进行引用,用了SpEL在bean标签中可以用value代替ref。
可以像EL一样用点运算符调用方法以及对象中的属性。
计算表达式的值
正则表达式的匹配。

SpEL 字面量,意义不大,spring内部本身有数据类型的自动转换机制,直接写值就好了,不必用SqEL,了解:

整数:#{8}   实际上,直接写成“8”即可,如前面讲的:p:id="1",就表示1
小数:#{8.8}
科学计数法:#{1e4}
String:可以使用单引号或者双引号作为字符串的定界符号。
Boolean:#{true}

SpEL引用bean , 调用它属性和方法:

引用其他对象:#{car}
引用其他对象的属性:#{car.price}
调用其它方法 , 还可以链式操作:#{person.pet.toString()}
调用静态方法静态属性:#{T(java.lang.Math).PI}
Spring EL 操作List、Map集合取值//SpEL支持的运算符号:算术运算符:+,-,*,/,%,^(加号还可以用作字符串连接)
比较运算符:< , > , == , >= , <= , lt , gt , eg , le , ge
逻辑运算符:and , or , not , |
if-else 运算符(类似三目运算符):?:(temary), ?:(Elvis)
正则表达式:#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'}

例:引用对象举例
       为了测试,我在Pet类中,添加成员属性private double price及get/set方法,在Person类中添属性成员private double petPrice,private double pi及get/set方法,petPrice属性在spring创建对象时,引用Pet对象中定义的值,pi属性引用lang包中的静态成员常量。

   <!-- springEL,测试 --><bean id="cat1" class="cn.ybzy.springdemo.model.Pet" p:id="1" p:type="cat" p:price="1000.0"></bean><bean id="person" class="cn.ybzy.springdemo.model.Person"><property name="id" value="1"></property><property name="pet" value="#{cat1}"></property><property name="petPrice" value="#{cat1.price}"></property><property name="pi" value="#{T(java.lang.Math).PI}"></property></bean>
	/** spring EL 测试*/@Testpublic void springEltest() {ApplicationContext ct = new ClassPathXmlApplicationContext("springEL.xml");Person person=(Person)ct.getBean("person");System.out.println(person);System.out.println(person.getPi());}
--------------------------------------------------------------------
Person [id=1, pet=Pet [id=1, type=cat, price=1000.0], cars=null, petPrice=1000.0]
3.141592653589793	

例:springEL运算符演示,这里我只举,三目运算会和正则表达式匹配运算
       为了测试,我在Person类中添加test属性,private String test及get/set方法,它会根根价格来作两个判 断,大于800元,是土豪,小于100元是普通人养宠物。

 <property name="test" value="#{cat1.price > 800 ? '土豪' : '普通人'}"></property>
   System.out.println(person.getTest());
---------------------------------------------------------------------
土豪

正则表达式测试,字符串 ''aaaa98734"不全是数字,所以匹配0-9多个数字是错的

<property name="test" value="#{'aaa98734' matches '[0-9]+'}"></property>
  System.out.println(person.getTest());
---------------------------------------------------------------------
false

例:引用List,Map
在这里插入图片描述
map[‘1’]中的1是KEY
在这里插入图片描述

Spring通过工厂方法进行配置

       在Spring的世界中, 我们通常会利用 xml配置文件 或者 annotation注解方式来配置bean实例!
在第一种利用 xml配置文件 方式中, 还包括如下三小类

  1. 反射模式(我们前面的所有配置都是这种模式)
  2. 工厂方法模式
  3. Factory Bean模式

工厂方法进行配置
       静态工厂方法方式是非常适用于作为1个bean容器, 只不过bean集合定义在工厂类里面而不是项目xml配置文件里面。
       缺点也比较明显, 把数据写在class里面而不是配置文件中违反了我们程序猿的常识和spring的初衷。当然优点就是令人恶心的xml配置文件更加简洁。所以,工厂方法的配置,了解一下就行了,个人建议不要在项目中使用,但要了解,以后看到项目中有这样的方式,能看得懂。

FactoryBean 来配置Bean

       spring通过FactoryBean配置,比前面的工厂方法配置Bean要重要些,因为我们整合很多第三方的框架的时候,需要用到FactoryBean来配置第三方框架中的bean 对象,从而把第三方框架整合到spring中来!当然在整合这些第三方框架的时候,这个FactoryBean一般都是我们引入的jar包中,人家给写好了的,我们会用就行,但知道原理也是好的!
例:通过FactoryBean接口的实现类CarFactoryBean,spring中配Car的bean:id="bwn"是CarFactoryBean的bean名,再通过构造方法注入Car的bean,则试:输出Car对象的toString()中的内容

CarFactoryBean.java

public class CarFactoryBean implements FactoryBean<Car>{private String type;public CarFactoryBean(String type) {this.type=type;}//返回我们要配置的Bean 对象@Overridepublic Car getObject() throws Exception {return new Car(101,type);}//返回我们配置的Bean 对象的类型@Overridepublic Class<?> getObjectType() {return Car.class;}

Car.java

public class Car {private int id;private String mark;   //品牌//get/set/toString,方法
}

factoryBean.xml

   <!-- 通过FactoryBean实现类CarFactoryBean,来注入一个宝码的Car实例对象 --><bean id="bwm" class="cn.ybzy.springdemo.model.CarFactoryBean"><constructor-arg  value="BWM"></constructor-arg><!-- 构造方法注入,当然也可属性注入,但我没有写type的set方法 --></bean>

测试类中:

@Testpublic void FactoryBeantest() {ConfigurableApplicationContext ct = new ClassPathXmlApplicationContext("factoryBean.xml");Car baomaCar = (Car) ct.getBean("bwm");System.out.println(baomaCar);}
----------------------------------------------------------------------------------------------------------------
Car [id=101, mark=BWM]

通过整合Quartz框架-定时做事用的,来演示看看,实际项目应用中,是怎么用FactoryBean来将第三方框架整合进入spring的!
1、导入spring-context-support,quartz等相关jar包

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.2.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>5.0.6.RELEASE</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.35</version></dependency><!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-nop</artifactId><version>1.7.35</version><scope>test</scope>
</dependency>

2、定义一个工作任务job

public class MyJob implements Job{@Overridepublic void execute(JobExecutionContext context) throws JobExecutionException {System.out.println("quartz我的具体的每次工作任务");}}

3、Spring配置文件中整合配置:
1)定义工作任务的Job
2)定义触发器Trigger,并将触发器与工作任务绑定
3)定义调度器,并将Trigger注册到Scheduler

!-- 定义工作任务的Job bean --><bean id="myJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><!-- 指定job的名称 --><property name="name" value="myQuartzJob"></property><!-- 指定job的分组 --><property name="group" value="myJobGroup"></property><!-- 指定具体的job类 --><property name="jobClass" value="cn.ybzy.springdemo.model.MyJob"></property><!-- 必须置为true,如果为false ,当没有活动的触发器与之关联时会在调度器中会删除该任务 --><property name="durability" value="true"></property><!--springIOC容器的KEY  --><property name="applicationContextJobDataKey" value="factoryBean"></property></bean><!-- 定义触发器Trigger,并将触发器与工作任务绑定 --><bean id="trigger"  class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><property name="name" value="myTrigger"></property><property name="group" value="myGroup"></property><!-- 指定Trigger绑定的job --><property name="jobDetail" ref="myJob"></property><!-- 指定Cron的表达式,当前是每隔3秒运行一次 --><property name="cronExpression" value="0/3 * * * * ?"></property></bean><!-- 调度器,并把Trigger注册到Scheduler --><bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref bean="trigger"/></list></property></bean>

一个cron表达式有至少6个(也可能7个)有空格分隔的时间元素。

CronTrigger配置完整格式为: [秒] [分] [小时] [日] [月] [周] [年]*表示所有值. 例如:在分的字段上设置 "*",表示每一分钟都会触发。? 表示不指定值。使用的场景为不需要关心当前设置这个字段的值。例如:要在每月的10号触发一个操作,但不关心是周几,所以需要周位置的那个字段设置为"?" 具体设置为 0 0 0 10 * ?- 表示区间。例如 在小时上设置 "10-12",表示 10,11,12点都会触发。, 表示指定多个值,例如在周字段上设置 "MON,WED,FRI" 表示周一,周三和周五触发/ 用于递增触发。如在秒上面设置"5/15" 表示从5秒开始,每增15秒触发(5,20,35,50)。

测试

	//FactoryBean测试,FactoryBean quartz定时任框架测试,但在junit不支持多线程,所以看不到每三秒执行的效果,我//另在model层中写一个类MyJob.java,用了main方法@Testpublic void FactoryBeantest() {
//		ConfigurableApplicationContext ct = new ClassPathXmlApplicationContext("factoryBean.xml");
//		Car baomaCar = (Car) ct.getBean("bwm");
//		System.out.println(baomaCar);ConfigurableApplicationContext ct = new ClassPathXmlApplicationContext("factoryBean.xml");SchedulerFactoryBean scheduler=(SchedulerFactoryBean)ct.getBean("scheduler");scheduler.start();}

MyJobTest.java—model层中(无所谓那层了)

public class MyJobTest {public static void main(String[] args) {ConfigurableApplicationContext ct = new ClassPathXmlApplicationContext("factoryBean.xml");SchedulerFactoryBean scheduler=(SchedulerFactoryBean)ct.getBean("scheduler");scheduler.start();}}
----------------------------------------------------------------------------------------------------------------
quartz我的具体的每次工作任务
quartz我的具体的每次工作任务
quartz我的具体的每次工作任务
。。。。。。。。。

注解配bean

       Spring引入了注解,通过"@XXX"的方式,让注解与Java Bean紧密结合,既大大减少了配置文件的体积,又增加了Java Bean的可读性与内聚性。
Spring注解配置初始化对象(<bean>):
spring中使用注解配置对象前,要在配置文件中配置<context:component-scan >标签告诉spring框架,配置了注解的类的位置配置文件applicationContext.xml:

<!--告诉sping,要创建的bean在springdemo包下及子包中所有类的bean-->
<context:component-scan  base-package="cn.ybzy.springdemo">
</context:component-scan>

注解说明:

       Component是最初spring框架设计的,后来为了标识不同代码层,衍生出Controller,Service,Repository三个注解 作用相当于配置文件的bean标签,被注解的类,spring始化时,就会创建该对象

@Component("user")  给类注解
@Service("user") // service层
@Controller("user") // web业务层
@Repository("user")//dao层
@Scope(scopeName="singleton") 等同于配置文件的scope属性@Value(value="188") //给值属性赋值,可以用在方法上或者属性上
@Resource(name="car") //给对象赋值,该值car必须要已经声明(在配置文件中已经配置,或者在类对应中已经注解)
@PostConstruct //指定该方法在对象被创建后马上调用 相当于配置文件中的init-method属性
@PreDestroy //指定该方法在对象销毁之前调用 相当于配置文件中的destory-method属性
@Autowired 用的非常多//自动装配对象赋值@Qualifier("car2") 一起使用 告诉spring容器自动装配哪个对象

例:Tiger.java,Monkey.java,Zoo.java,zhujieBean.xml,RunTest.java


@Component("tiger")
public class Tiger {@Value(value="东南虎")private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Tiger [name=" + name + "]";}
}
@Component("monkey")
public class Monkey {@Value("金丝猴")private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Monkey [name=" + name + "]";}}
@Component
public class Zoo {@Resource(name="tiger")private Tiger tiger;@Resource(type=Monkey.class)private Monkey monkey;public Tiger getTiger() {return tiger;}public void setTiger(Tiger tiger) {this.tiger = tiger;}public Monkey getMonkey() {return monkey;}public void setMonkey(Monkey monkey) {this.monkey = monkey;}@Overridepublic String toString() {return "Zoo [tiger=" + tiger.getName() + ", monkey=" + monkey.getName() + "]";}}
<!-- 注解配bean --><!-- 1.先非注解配bean(对象),让我们作个比较 --><!-- <bean name="tiger" class="cn.ybzy.springdemo.model.Tiger" p:name="东南虎"></bean><bean name="monkey" class="cn.ybzy.springdemo.model.Monkey" p:name="金丝猴"></bean><bean name="nanchangzoo" class="cn.ybzy.springdemo.model.Zoo" p:monkey-ref="monkey" p:tiger-ref="tiger"></bean>  --><!-- 2.注解配bean(对象),让我们作个比较 --><context:component-scan base-package="cn.ybzy.springdemo.model"></context:component-scan>

测试

//注解配bean测试@Testpublic void zhujieBeantest() {ApplicationContext ct = new ClassPathXmlApplicationContext("zhujieBean.xml");Tiger tiger=(Tiger)ct.getBean("tiger");System.out.println(tiger);//Zoo zoo = (Zoo)ct.getBean("nanchangzoo");Zoo zoo = (Zoo)ct.getBean("zoo");System.out.println(zoo);}
----------------------------------------------------------------------------------------------------------------
Tiger [name=东南虎]
Zoo [tiger=东南虎, monkey=金丝猴]

说一下@Resource的装配顺序:

1、@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
2、指定了name或者type则根据指定的类型去匹配bean
3、指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/81885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GStreamer (三)常⽤插件

常⽤插件 1、Source1.1、filesrc1.2. videotestsrc1.3. v4l2src1.4. rtspsrc和rtspclientsink 2、 Sink2.1. filesink2.2. fakesink2.3. xvimagesink2.4. kmssink2.5. waylandsink2.6. rkximagesink2.7. fpsdisplaysink 3 、视频推流/拉流3.1. 本地推流/拉流3.1.1 USB摄像头3.1…

【EDA软件】【联合Modelsim仿真使用方法】

背景 业界EDA工具仿真功能是必备的&#xff0c;例如Vivado自带仿真工具&#xff0c;且无需联合外部仿真工具&#xff0c;例如MoodelSim。 FUXI工具仿真功能需要联合Modelsim&#xff0c;才能实现仿真功能。 方法一&#xff1a;FUXI联合ModelSim 1 添加testbench文件 新建to…

国产化Excel处理组件Spire.XLS for .NET系列教程:通过 C# 将 TXT 文本转换为 Excel 表格

在数据处理和管理场景中&#xff0c;将原始文本文件&#xff08;TXT&#xff09;高效转换为结构化的 Excel 电子表格是一项常见要求。对于那些需要自动生成报表或者处理日志文件的开发人员而言&#xff0c;借助 C# 实现 TXT 到 Excel 的转换工作&#xff0c;可以简化数据组织和…

DeepSeek 的强化学习优化策略:RLHF 与 DPO 的应用

DeepSeek 的强化学习优化策略&#xff1a;RLHF 与 DPO 的应用 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 DeepSeek 的强化学习优化策略&#xff1a;RLHF 与 DPO 的应用摘要引言技术原理对比1. RLHF&#xff1a…

c: 分号的歧义

最近看到一个关于某些语言里的分号问题&#xff0c;比如下面一个作者就是无意识的每行后面多加了分号导致问题。 其实python的语法可以更好的规避这种潜意识&#xff0c;因为根本就不需要每行后面加分号的意识&#xff0c;也就不需要开发者习惯这种意识。 所以&#xff0c;最后…

Elasticsearch 实战面试题,每个题目都会单独解析

Elasticsearch 在 Java 中最常用的客户端是什么&#xff1f;如何初始化一个 RestHighLevelClient&#xff1f;如何用 Spring Boot 快速集成 Elasticsearch&#xff1f;Spring Data Elasticsearch 如何定义实体类与索引的映射&#xff1f; ES的倒排索引和正排索引的区别及适用场…

拉普拉斯高斯(LoG)滤波器掩模的注意事项

目录 问题&#xff1a; 解答&#xff1a; 一、高斯函数归一化&#xff1a;消除幅度偏差 1. 归一化的定义 2. 为何必须归一化&#xff1f; 二、拉普拉斯系数和为零&#xff1a;抑制直流项干扰 1. 拉普拉斯算子的特性 2. 系数和不为零的后果 三、直流项如何影响零交叉点&…

运维实施35-磁盘管理

了解磁盘 硬盘的接口类型 接口类型发展方向应用场景IDESATA I/II/III个人PC机SCSISAS服务器上 磁盘命名规则 OSIDE(并口)SATA(串口)SCSIRHEL5/dev/hda/dev/sda/dev/sdaRHEL6/dev/sda/dev/sda/dev/sdaRHEL7/dev/sda/dev/sda/dev/sda 磁盘设备的命名 /dev/sda2 s 硬件接口…

API面临哪些风险,如何做好API安全?

API面临的风险 API&#xff08;应用程序编程接口&#xff09;在现代软件开发和集成中扮演着至关重要的角色&#xff0c;但同时也面临着多种安全风险&#xff0c;主要包括以下几个方面&#xff1a; 数据泄露风险&#xff1a; API通常涉及敏感数据的传输和交换&#xff0c;如用…

`application-{env}.yml` 配置文件来实现多环境配置

在 Spring Boot 应用中&#xff0c;使用多套 application-{env}.yml 配置文件来实现多环境配置是一种常见且推荐的做法。这种方式可以帮助你根据不同的环境&#xff08;如开发、测试、生产等&#xff09;加载不同的配置&#xff0c;从而实现环境隔离和灵活配置。以下是如何通过…

野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(一)conda环境搭建

先安装miniconda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh chmod x Miniconda3-latest-Linux-aarch64.sh bash Miniconda3-latest-Linux-aarch64.sh source ~/.bashrc conda --version按照MobileFaceNet的github官方指南&#xff0c;需要…

目标检测 Lite-DETR(2023)详细解读

文章目录 迭代高级特征跨尺度融合高效的低层次特征跨尺度融合KDA&#xff1a;Key-aware Deformable Attention 论文翻译&#xff1a; CVPR 2023 | Lite DETR&#xff1a;计算量减少60%&#xff01;高效交错多尺度编码器-CSDN博客 DINO团队的 &#xff08;Lightweight Transfo…

【Git】远程操作

Git 是一个分布式版本控制系统 可以简单理解为&#xff0c;每个人的电脑上都是一个完整的版本库&#xff0c;这样在工作时&#xff0c;就不需要联网 了&#xff0c;因为版本库就在自己的电脑上。 因此&#xff0c; 多个人协作的方式&#xff0c;譬如说甲在自己的电脑上改了文件…

华为云Flexus+DeepSeek征文|基于华为云Flexus云服务的Dify 构建智能客服助手

目录 一、构建智能客服助手应用 二、构建智能客服助手提示词 2.1 什么是智能客服助手&#xff1f; 2.2 生成智能客服助手提示词 三、访问智能客服助手 3.1 智能客服助手发布 3.2 智能客服助手聊天 3.3 开启新会话 四、总结 本篇文章主要基于华为云Flexus云服务的Dify 构…

基于单片机的矩阵键盘与数码管显示实验实践

在单片机开发领域&#xff0c;掌握基础的输入输出控制是迈向复杂项目的关键一步。本次实验聚焦于利用单片机开发板&#xff0c;通过矩阵键盘实现学号后 8 位的输入与数码管显示&#xff0c;旨在掌握数码管显示、软件延时以及键盘扫描及去抖动等核心方法。接下来&#xff0c;就带…

GO语言语法---switch语句

文章目录 基本语法1. 特点1.1 不需要break1.2 表达式可以是任何类型1.3 省略比较表达式1.4 多值匹配1.5 类型switch1.6 case穿透1.7 switch后直接声明变量1.7.1 基本语法1.7.2 带比较表达式1.7.3 不带比较表达式1.7.4 结合类型判断 1.8 switch后的表达式必须与case语句中的表达…

GO语言学习(三)

GO语言学习&#xff08;三&#xff09; GO语言的独特接口可以实现内容和面向对象组织的更加方便&#xff0c;我们从这里来详细的讲解接口&#xff0c;让大家感受一下interface的魅力 interface定义 首先接口是一组方法签名的组合&#xff0c;我们通过接口来实现定义对象的一…

anaconda创建环境出错HTTPS

报错信息 warnings.warn( /home/ti-3/anaconda3/lib/python3.12/site-packages/urllib3/connectionpool.py:1099: InsecureRequestWarning: Unverified HTTPS request is being made to host ‘repo.anaconda.com’. Adding certificate verification is strongly advised. Se…

Android 自定义SnackBar和下滑取消

如何自定义SnackBar 首先我们得了解SnackBar的布局&#xff1a; 之前我看有一些方案是获取内部的contentLayout&#xff0c;然后做一些处理。但是现在已经行不通了&#xff1a; RestrictTo(LIBRARY_GROUP) public static final class SnackbarLayout extends BaseTransientB…

JavaScript性能优化实战(13):性能测试与持续优化

在前面的系列文章中,我们探讨了各种JavaScript性能优化的方法和实战案例。然而,优化工作不应仅是一次性的努力,而应当成为开发流程中的常态。本篇将聚焦于如何建立系统化的性能测试体系,并实现持续的性能优化机制,确保应用长期保持出色的性能表现。 前端性能测试体系构建…