SpringBoot自动配置

项目内部配置第三方bean

  1. 第三方的bean通过配置类的@bean注入,项目内部引用使用@Import配置类的class

  2. 解耦引入的第三方配置类, 新建一个缓冲类加载需要引入的配置类

  3. 将需要引入第三方配置类加入Mate-inf中的factories中

  4. 加载返回可以引入第三方的bean

  5. 本项目bean和第三方bean冲突,以本项目为准(import先解析被覆盖,默认不可以覆盖)

    1. DeferredImportSelector推迟导入,先解析本项目的

    2. @ConditionalOnMissingBean本项目没有,则加载第三方的

package com.butch.a41;import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.ResourcePropertySource;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;import java.io.IOException;
import java.util.List;
import java.util.Map;public class A41_1 {@SuppressWarnings("all")public static void main(String[] args) throws IOException {GenericApplicationContext context = new GenericApplicationContext();context.getDefaultListableBeanFactory().setAllowBeanDefinitionOverriding(false);context.registerBean("config", Config.class);context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");System.out.println(context.getBean(Bean1.class));}@Configuration // 本项目的配置类@Import(MyImportSelector.class)static class Config {@Beanpublic Bean1 bean1() {return new Bean1("本项目");}}static class MyImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {
//            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");//EnableAutoConfiguration为key的类名
//            for (String name : SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, null)) {
//                System.out.println(name);
//            }
//            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");//获取配置文件中值 也会扫描第三方jar包的factoriesList<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class, null);return names.toArray(new String[0]);}}@Configuration // 第三方的配置类static class AutoConfiguration1 {@Bean@ConditionalOnMissingBeanpublic Bean1 bean1() {return new Bean1("第三方");}}static class Bean1 {private String name;public Bean1() {}public Bean1(String name) {this.name = name;}@Overridepublic String toString() {return "Bean1{" +"name='" + name + '\'' +'}';}}@Configuration // 第三方的配置类static class AutoConfiguration2 {@Beanpublic Bean2 bean2() {return new Bean2();}}static class Bean2 {}
}

自动配置实现类

AopAutoConfiguration(AOP)
  • AOP 自动配置类为 org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

  • 可以通过 spring.aop.auto=false 禁用 aop 自动配置

  • AOP 自动配置的本质是通过 @EnableAspectJAutoProxy 来开启了自动代理,如果在引导类上自己添加了 @EnableAspectJAutoProxy 那么以自己添加的为准

  • @EnableAspectJAutoProxy 的本质是向容器中添加了 AnnotationAwareAspectJAutoProxyCreator 这个 bean 后处理器,它能够找到容器中所有切面,并为匹配切点的目标类创建代理,创建代理的工作一般是在 bean 的初始化阶段完成的

多层嵌套的静态内部类,最后一层EnableAspectJAutoProxy 导入代理创建器

  1. spring.aop.auto!= false才加载

  2. @ConditionalOnClass(Advice.class)存在Advice

  3. @ConditionalOnMissingClass("org.aspectj.weaver.Advice") 缺失条件

  4. 最终@EnableAspectJAutoProxy 本质是import,proxyTargetClass创建代理的模式,为false会看看有没有实现接口有接口jdk代理

  5. 最终注册AnnotationAwareAspectJAutoProxyCreator的bean后处理器,高层转底层创建jdk或者cglib代理

package com.butch.a41;import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.AnnotationMetadata;public class TestAopAuto {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();StandardEnvironment env = new StandardEnvironment();env.getPropertySources().addLast(new SimpleCommandLinePropertySource("--spring.aop.auto=true"));context.setEnvironment(env);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.registerBean(Config.class);context.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}//org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$AspectJAutoProxyingConfiguration$CglibAutoProxyConfiguration//org.springframework.aop.config.internalAutoProxyCreator//org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$AspectJAutoProxyingConfiguration//org.springframework.boot.autoconfigure.aop.AopAutoConfigurationSystem.out.println(">>>>>>>>>>>>>>>");//查看代理实现类型AnnotationAwareAspectJAutoProxyCreator creator = context.getBean("org.springframework.aop.config.internalAutoProxyCreator", AnnotationAwareAspectJAutoProxyCreator.class);System.out.println(creator.isProxyTargetClass());}@Configuration@Import(MyImportSelector.class)static class Config {}static class MyImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{AopAutoConfiguration.class.getName()};}}
}
Datasource
  • 对应的自动配置类为:org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

  • 它内部采用了条件装配,通过检查容器的 bean,以及类路径下的 class,来决定该 @Bean 是否生效

简单说明一下,Spring Boot 支持两大类数据源:

  • EmbeddedDatabase - 内嵌数据库连接池

  • PooledDataSource - 非内嵌数据库连接池

PooledDataSource 又支持如下数据源

  • hikari 提供的 HikariDataSource

  • tomcat-jdbc 提供的 DataSource

  • dbcp2 提供的 BasicDataSource

  • oracle 提供的 PoolDataSourceImpl

如果知道数据源的实现类类型,即指定了 spring.datasource.type,理论上可以支持所有数据源,但这样做的一个最大问题是无法订制每种数据源的详细配置(如最大、最小连接数等)

dataSource

  1. @Conditional(PooledDataSourceCondition.class)进入带有连接池的数据源

  2. 集成mybaits依赖jdbc进入@ConditionalOnClass(HikariDataSource.class)

  3. @EnableConfigurationProperties(DataSourceProperties.class)封装绑定键值信息,spring.datasourcexxxxx

    1. 创建datasource绑定键值信息

mybits
  • MyBatis 自动配置类为 org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration

  • 它主要配置了两个 bean

    • SqlSessionFactory - MyBatis 核心对象,用来创建 SqlSession

    • SqlSessionTemplate - SqlSession 的实现,此实现会与当前线程绑定

    • 用 ImportBeanDefinitionRegistrar 的方式扫描所有标注了 @Mapper 注解的接口

    • 用 AutoConfigurationPackages 来确定扫描的包

  • 还有一个相关的 bean:MybatisProperties,它会读取配置文件中带 mybatis. 前缀的配置项进行定制配置

@MapperScan 注解的作用与 MybatisAutoConfiguration 类似,会注册 MapperScannerConfigurer 有如下区别

  • @MapperScan 扫描具体包(当然也可以配置关注哪个注解)

  • @MapperScan 如果不指定扫描具体包,则会把引导类范围内,所有接口当做 Mapper 接口

  • MybatisAutoConfiguration 关注的是所有标注 @Mapper 注解的接口,会忽略掉非 @Mapper 标注的接口

  • 其实并非将接口交给 Spring 管理,而是每个接口会对应一个 MapperFactoryBean,是后者被 Spring 所管理,接口只是作为 MapperFactoryBean 的一个属性来配置

package com.butch.a41;import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DeferredImportSelector;
import org.springframework.context.annotation.Import;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.type.AnnotationMetadata;public class TestDataSourceAuto {@SuppressWarnings("all")public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();StandardEnvironment env = new StandardEnvironment();//添加配置源env.getPropertySources().addLast(new SimpleCommandLinePropertySource("--spring.datasource.url=jdbc:mysql://localhost:3306/test","--spring.datasource.username=root","--spring.datasource.password=123456"));context.setEnvironment(env);AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.registerBean(Config.class);String packageName = TestDataSourceAuto.class.getPackage().getName();System.out.println("当前包名:" + packageName);AutoConfigurationPackages.register(context.getDefaultListableBeanFactory(),packageName);context.refresh();for (String name : context.getBeanDefinitionNames()) {String resourceDescription = context.getBeanDefinition(name).getResourceDescription();if (resourceDescription != null)System.out.println(name + " 来源:" + resourceDescription);//dataSource 来源:class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]//hikariPoolDataSourceMetadataProvider 来源:class path resource [org/springframework/boot/autoconfigure/jdbc/metadata/DataSourcePoolMetadataProvidersConfiguration$HikariPoolDataSourceMetadataProviderConfiguration.class]//sqlSessionFactory 来源:class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]//sqlSessionTemplate 来源:class path resource [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]//transactionManager 来源:class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration$DataSourceTransactionManagerConfiguration.class]//org.springframework.transaction.config.internalTransactionAdvisor 来源:class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]//transactionAttributeSource 来源:class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]//transactionInterceptor 来源:class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]//org.springframework.transaction.config.internalTransactionalEventListenerFactory 来源:class path resource [org/springframework/transaction/annotation/ProxyTransactionManagementConfiguration.class]//transactionTemplate 来源:class path resource [org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration$TransactionTemplateConfiguration.class]//platformTransactionManagerCustomizers 来源:class path resource [org/springframework/boot/autoconfigure/transaction/TransactionAutoConfiguration.class]}}@Configuration@Import(MyImportSelector.class)static class Config {}static class MyImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{//配置数据源 必选DataSourceAutoConfiguration.class.getName(),//mybit的sqlsession工程mapper扫描MybatisAutoConfiguration.class.getName(),//事务管理DataSourceTransactionManagerAutoConfiguration.class.getName(),//声明式事务管理TransactionAutoConfiguration.class.getName()};}}
}

 

TransactionAutoConfiguration
  • 事务自动配置类有两个:

    • org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration

    • org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration

  • 前者配置了 DataSourceTransactionManager 用来执行事务的提交、回滚操作

  • 后者功能上对标 @EnableTransactionManagement,包含以下三个 bean

    • BeanFactoryTransactionAttributeSourceAdvisor 事务切面类,包含通知和切点

    • TransactionInterceptor 事务通知类,由它在目标方法调用前后加入事务操作

    • AnnotationTransactionAttributeSource 会解析 @Transactional 及事务属性,也包含了切点功能

  • 如果自己配置了 DataSourceTransactionManager 或是在引导类加了 @EnableTransactionManagement,则以自己配置的为准

WebMvcAutoConfiguration
  • 配置 DispatcherServlet 的各项组件,提供的 bean 见过的有

    • 多项 HandlerMapping

    • 多项 HandlerAdapter

    • HandlerExceptionResolver

自定义自动配置类

  1. 自动配置类本质上就是一个配置类而已,只是用 META-INF/spring.factories 管理,与应用配置类解耦

  2. @Enable 打头的注解本质是利用了 @Import

  3. @Import 配合 DeferredImportSelector 即可实现导入,selectImports 方法的返回值即为要导入的配置类名

  4. DeferredImportSelector 的导入会在最后执行,为的是让其它配置优先解析

package com.butch.a41;import org.springframework.boot.autoconfigure.AutoConfigurationImportSelector;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.SimpleCommandLinePropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.AnnotationMetadata;import java.io.IOException;
import java.util.List;public class A41_2 {@SuppressWarnings("all")public static void main(String[] args) throws IOException {GenericApplicationContext context = new GenericApplicationContext();StandardEnvironment env = new StandardEnvironment();env.getPropertySources().addLast(new SimpleCommandLinePropertySource("--spring.datasource.url=jdbc:mysql://localhost:3306/test","--spring.datasource.username=root","--spring.datasource.password=root"));context.setEnvironment(env);        context.registerBean("config", Config.class);context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>");System.out.println(context.getBean(Bean1.class));}//spring识别的import
//    @Import(AutoConfigurationImportSelector.class)
//    @Import(MyImportSelector.class)@EnableAutoConfiguration@Configuration // 本项目的配置类static class Config {}static class MyImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {
//            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");//EnableAutoConfiguration为key的类名
//            for (String name : SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, null)) {
//                System.out.println(name);
//            }
//            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");//获取配置文件中值List<String> names = SpringFactoriesLoader.loadFactoryNames(MyImportSelector.class, null);return names.toArray(new String[0]);}}@Configuration // 第三方的配置类static class AutoConfiguration1 {@Beanpublic Bean1 bean1() {return new Bean1();}}@Configuration // 第三方的配置类static class AutoConfiguration2 {@Beanpublic Bean2 bean2() {return new Bean2();}}static class Bean2 {}static class Bean1 {}
}

条件装配底层

当引入第三方的bean ,增加条件装配

底层使用conditional 配合实现了condition的接口进行检查

本质上是if-else语句

package com.butch.a42;import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;public class A42_2 {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();context.registerBean("config", Config.class);context.registerBean(ConfigurationClassPostProcessor.class);context.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}}@Configuration // 本项目的配置类@Import(MyImportSelector.class)static class Config {}static class MyImportSelector implements DeferredImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{AutoConfiguration1.class.getName(), AutoConfiguration2.class.getName()};}}static class Mycondition1 implements Condition{//检测德鲁伊存在@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {System.out.println("ClassUtils.isPresent(\"DruidDataSource\", null)" + ClassUtils.isPresent("DruidDataSource", null));return ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource" +"", null);}}static class Mycondition2 implements Condition{//检测德鲁伊不存在@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {return !ClassUtils.isPresent("com.alibaba.druid.pool.DruidDataSource", null);}}//    @ConditionalOnClass(className = "com.alibaba.druid.pool.DruidDataSource", exists = false) //有德鲁伊bean1 无德鲁伊bean2@Configuration // 第三方的配置类@Conditional(Mycondition1.class)static class AutoConfiguration1 {@Beanpublic Bean1 bean1() {return new Bean1();}}@Configuration // 第三方的配置类
//    @ConditionalOnClass(className = "com.alibaba.druid.pool.DruidDataSource", exists = true)@Conditional(Mycondition2.class)static class AutoConfiguration2 {@Beanpublic Bean2 bean2() {return new Bean2();}}static class Bean1 {}static class Bean2 {}
}

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

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

相关文章

软考《信息系统运行管理员》-2.3信息系统运维的外包

2.3信息系统运维的外包 信息系统运维外包的概念/模式 也称为信息系统代维。是指信息系统使用单位将全部或一部分的信息系统维护服务工作&#xff0c;按照规定的维护服务要求&#xff0c;外包委托给专业公司管理。 完全外包运维模式部分外包模式 信息系统运维外包的好处 有利…

offer150-16:数值的整数次方

题目描述:实现函数double Power(double base,int exponent),求base 的exponent次方。不得使用库函数&#xff0c;同时不需要考虑大数问题。 分析&#xff0c;题目要求实现库函数pow(),由于不需要考虑大数问题&#xff0c;不必担心溢出&#xff0c;那么就需要对输入的各种情况进…

预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来

预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来 目录 预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.预测未来 | Matlab实现HMM隐马尔科夫时间序列预测未来 2.运行环境为Matlab2023b及以上&#xff1b; 3…

路径跟踪算法---Stanley Method实现

文章目录 前言一、Stanley原理介绍二、主要代码实现三、效果 前言 Stanley Controller也是基于几何追踪的轨迹跟踪控制器&#xff0c;和Pure Pursuit不同的是&#xff0c;其基于前轮中心点为参考点进行控制&#xff0c;没有预瞄距离&#xff0c;以前轮中心点与最近参考轨迹点进…

天诚长租公寓智能门锁管理解决方案

人才是区域创新发展的第一资源&#xff0c;如何解决人才的住房问题&#xff0c;让人才“流进来”、“留下来”、“融进来”&#xff0c;就需要优先安排优质人才公寓、人才优租房和公共租赁住房房源&#xff0c;并为青年人才群体提供智能化、信息化的租住体验及通行服务。 一、…

四、(1)网络爬虫入门及准备工作(爬虫及数据可视化)

四、&#xff08;1&#xff09;网络爬虫入门及准备工作&#xff08;爬虫及数据可视化&#xff09; 1&#xff0c;网络爬虫入门1.1 百度指数1.2 天眼查1.3 爬虫原理1.4 搜索引擎原理 2&#xff0c;准备工作2.1 分析爬取页面2.2 爬虫拿到的不仅是网页还是网页的源代码2.3 爬虫就是…

数据库完整性约束:确保数据准确性的关键

目录 &#x1f397;一、实体完整性 示例&#xff1a;定义主键 &#x1f38a;二、参照完整性 示例&#xff1a;定义外键 &#x1f380;三、域完整性 示例&#xff1a;定义非空和唯一约束 &#x1f381;四、用户定义的完整性 示例&#xff1a;定义自定义约束 &#x1f3…

arthas监控工具笔记(二)monior等

文章目录 monitor/watch/trace 相关monitormonitor例子monitor -c <value>monitor -m <vaule>monitor 条件表达式monitor -b monitor文档(界面描述)monitor文档(help) stack - 输出当前方法被调用的调用路径trace - 方法内部调用路径&#xff0c;并输出方法路径上的…

c++中c_str()及atof()和stod()的用法详细解析

文章目录 函数作用语法及返回值使用方法1使用方法2atof函数的用法std::stod()函数的用法小结 函数作用 功能&#xff1a;c_str() 函数可以将 const string* 类型 转化为 const char* 类型 头文件&#xff1a;#include<cstring> 为了与c语言兼容&#xff0c;在c语言…

app单页下载页源码带管理后台

新版带后台管理APP应用下载页,自动识别安卓苹果下载页&#xff0c;带管理后台&#xff0c;内置带3套App下载模板带中文模板/英文模板随时切换。 app单页下载页源码带管理后台

nginx 配置文件location块中符号的含义

nginx -t 检查配置文件语法问题 nginx -s reload 重新加载conf文件 location 块 表示精确匹配 ~ 这个符号开头表示区分大小写 * 一般和 ~ 公用, ~* 表示不区分大小写 ^ 表示正则的开始 前缀匹配&#xff1a;默认的匹配方式&#xff0c;不带修饰符&#xff0c;匹配…

自动装配在Spring框架中的原理与实现方式

自动装配在Spring框架中的原理与实现方式 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 自动装配的概念与背景 在Spring框架中&#xff0c;自动装配&#x…

告别PS修图,设计师都在用的AI抠图工具

引言 大家好&#xff01;如果你是美工或设计师&#xff0c;肯定深知Photoshop修图的繁琐和耗时。现在有一款超方便的工具&#xff0c;让你摆脱这些问题——千鹿设计助手。它不仅是个抠图工具&#xff0c;还能通过先进的AI技术&#xff0c;让抠图变得简单快速&#xff0c;让你专…

[Leetcode 128][Medium] 最长连续序列

目录 题目描述 整体思路 具体代码 题目描述 原题链接 整体思路 首先看到找连续升序排序的最长序列长度&#xff0c;想到对数组进行排序预处理。但是排序算法时间复杂度需要O(nlogn)&#xff0c;题目要求时间复杂度为O(n)。因此不能进行排序与处理 接着想到数据结构哈希表&a…

Laravel 文件操作全指南:上传与下载实践

Laravel 提供了一系列强大的工具来简化文件上传和下载的过程&#xff0c;使得在 Web 应用程序中处理文件变得更加容易和安全。本文将详细介绍如何在 Laravel 中实现文件的上传和下载&#xff0c;包括表单创建、路由设置、控制器逻辑以及安全性考虑。 文件上传基础 文件上传是…

为什么网上商店需要翻译成其他语言

网上商店不仅仅是一个可以买到商品的网站。它是一个完整的电子商务平台&#xff0c;为来自世界各地的用户提供购买所需物品的机会。但是&#xff0c;为了让这些用户舒适地使用网站&#xff0c;需要高质量的翻译和本地化。 本地化是指产品或服务适应特定文化或市场的过程。它包…

问题 P: 表达式树的值

问题 P: 表达式树的值 题目描述 读入表达式树的先序遍历字符串&#xff0c;求其值。运算符只可能是加减乘除&#xff0c;保证输入的每个子表达式树的结果都是整数值且可以用C语言的int类型表达。 输入 输入由多组测试数据组成。 每组数据包含一行字符串&#xff0c;即表达式…

Nginx详解-安装配置等

目录 一、引言 1.1 代理问题 1.2 负载均衡问题 1.3 资源优化 1.4 Nginx处理 二、Nginx概述 三、Nginx的安装 3.1 安装Nginx 3.2 Nginx的配置文件 四、Nginx的反向代理【重点】 4.1 正向代理和反向代理介绍 4.2 基于Nginx实现反向代理 4.3 关于Nginx的location路径…

CSS 文本输入框右下角的尺寸控件(三斜线:-webkit-resizer)消除,以及如何配置其样式,添加 resize 让标签元素可进行拖拽放大。

前言&#xff1a;在日常的前端开发中&#xff0c;不管是原始的和 还在在各类组件库中的文本输入框中&#xff0c;元素内容的右下角总是有一个三斜线的样式&#xff0c;本文简单了解它是什么&#xff1f;如何去控制并修改样式&#xff1f; 一、它是&#xff1f; 这三个斜线其实…

echarts实现3D柱状图(视觉层面)

一、第一种效果 效果图 使用步骤 完整实例&#xff0c;copy就可直接使用 <template><div :class"className" :style"{height:height,width:width}" /> </template><script>import echarts from echartsrequire(echarts/theme/…