【微服务】spring 控制bean加载顺序使用详解
目录
一、前言
二、使用@order注解控制顺序
2.1 @order 注解使用示例
2.2 order注解顺序失效问题
2.2.1 @order失效问题解决办法
2.3 实现Ordered接口
三、使用@dependon注解控制顺序
四、AutoConfiguration注解控制bean加载顺序
4.1 @AutoConfigureBefore 操作演示
4.2 @AutoConfigureOrder 操作演示
4.3 源码解读与分析
五、自定义ApplicationContextInitializer
5.1 ApplicationContextInitializer介绍
5.2 ApplicationContextInitializer使用
5.3 ApplicationContextInitializer控制加载顺序
六、使用场景
6.1 解决bean的依赖关系
6.2 设置某些配置类的优先级最高
6.3 依赖传递
七、写在文末
一、前言
在使用spring框架开发过程中,可能会遇到下面的情况:
- 某个bean被另一个bean依赖,也就是bean-b的创建必须依赖bean-a;
- 某个bean被很多其他bean依赖,比如bean-a初始化完成后,其他bean需要依靠bean-a初始化自己的业务;
- ...
类似这样的场景还有很多,总结来说,这就涉及到bean的加载顺序问题,如何解决呢?下面列举出几种常用的解决方案。
二、使用@order注解控制顺序
@order注解是spring-core包下的一个注解,@Order的作用是定义Spring IOC容器中Bean的执行顺序的优先级(这里的顺序也可以理解为存放到容器中的先后顺序)。开发过程当中有时候经常会出现配置依赖关系,例如注入A对象使用了@ConditionalOnBean(B.class),意思是要求容器当中必须存在B.class的实例的时候,才会进行注入A。这时候我们就必须保证B对象在注入A对象前进行注入。
2.1 @order 注解使用示例
有如下两个类,Demo1和Demo2,分别在类上添加@Order注解
@Component
@Order(1)
public class Demo1 {@Beanpublic UserService serviceA(){System.out.println("serviceA 执行");return new UserService();}
}
两个类各自创建一个UserService的bean
@Component
@Order(2)
public class Demo2 {@Beanpublic UserService serviceB(){System.out.println("serviceB 执行");return new UserService();}
}
运行下面的代码,观察测试效果
public class OrderTest {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanScanConfig.class);String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();for(String beanName : beanDefinitionNames){System.out.println(beanName);}}
}
可以看到,order数字更小的demo1这个类的bean比demo2的bean要先创建出来;
2.2 order注解顺序失效问题
上面通过在类上添加@order,可以控制类创建的bean的顺序,事实真的如此吗?如果此时,我们将demo1的order调大,demo2的order数字调小,你将看到的效果仍然是serviceA先输出,这就是order注解顺序失效问题。关于这个问题,spring官方文档也有说明,翻译出来意思如下:
您可以在目标类级别和@Bean方法上声明@Order注释,可能针对的是单个bean定义(如果多个定义使用同一个bean类)。@Order值可能会影响注入点的优先级,但请注意,它们不会影响单例启动顺序,这是由依赖关系和@DependsOn声明确定的正交关注。
2.2.1 @order失效问题解决办法
解决方式1
将需要控制bean的创建顺序的两个类放到不同的包路径下
再次运行测试代码,当demo2的order数字更小的情况下,就能看到预期的demo2创建的bean优先输出的效果了
解决方式2
重新修改类的命名,比如将demo2的类修改为ADemo,让ADemo这个类在同一个包路径下置于Demo2之前
这样修改后,再次运行测试代码观察效果,此时ADemo就优先Demo1了
2.3 实现Ordered接口
使用spring提供的ordered接口,只需要自定义的类实现这个接口,并重写里面的getOrder方法,在getOrder方法的返回值中,数值越小,优先级越高,如下自定义两个被sppring管理的类,实现Ordered接口
@Component
public class Listener1 implements Ordered {@Beanpublic UserService userService1(){System.out.println("userService1 bean");return new UserService();}@Overridepublic int getOrder() {return 100;}
}
@Component
public class Listener2 implements Ordered {@Beanpublic UserService userService2(){System.out.println("userService2 bean");return new UserService();}@Overridepublic int getOrder() {return 10;}
}
与ordered接口类似的还有PriorityOrdered,用法大同小异,有兴趣的同学可以进一步挖掘。
三、使用@dependon注解控制顺序
当某个bean-a的创建或加载需要明确依赖另一个bean-b的时候可以考虑使用dependon注解,换言之,bean-b要优先于bean-a创建;
如下有两个类,OrderDemo1和OrderDemo2
@Component
@DependsOn("orderDemo2")
public class OrderDemo1 {public OrderDemo1(){System.out.println("OrderDemo1 ...");}}
其中OrderDemo1的创建依赖OrderDemo2
@Component
public class OrderDemo2 {public OrderDemo2(){System.out.println("OrderDemo2 ...");}}
运行程序,可以看到OrderDemo2优先于OrderDemo1创建
由于这种方法是通过bean的名字(字符串)来控制顺序的,如果改了bean的类名,很可能就会忘记来改所有用到它的注解,那就问题大了,所以这种方式一般不推荐使用,但是也不失为控制bean创建顺序的方式。
四、AutoConfiguration注解控制bean加载顺序
Spring Boot会根据当前容器内的情况来动态的判断自动配置类的配置顺序,它给我们提供了@AutoConfigureBefore、@AutoConfigureAfter、@AutoConfigureOrder 三大注解:
@AutoConfigureBefore
用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之后配置加载
@AutoConfigureAfter
用在自动配置类上面,表示该自动配置类需要在另外指定的自动配置类配置完之前配置加载
@AutoConfigureOrder
确定配置加载的优先级顺序,表示绝对顺序(数字越小,优先顺序越高)
4.1 @AutoConfigureBefore 操作演示
定义两个配置类DbConfig1与DbConfig2,代码如下
@Configuration
public class DbConfig1 {public DbConfig1(){System.out.println("DbConfig1 构建方法...");}}
其中,DbConfig2类上使用了注解AutoConfigureBefore,期望DbConfig2比DbConfig1先加载
@Configuration
@AutoConfigureBefore(DbConfig1.class)
public class DbConfig2 {public DbConfig2(){System.out.println("DbConfig2 构建方法...");}}
到这里还没有完事,还需在resources目录下,将DbConfig1与DbConfig2配置到spring.factories文件中进行自动装配
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.congge.config.DbConfig2,\
com.congge.config.DbConfig1
运行上面的代码,观察控制台输出,可以看到DbConfig2比DbConfig1先加载
我们还可以将注解换成AutoConfigureAfter,看看是什么效果
@Configuration
@AutoConfigureAfter(DbConfig1.class)
public class DbConfig2 {public DbConfig2(){System.out.println("DbConfig2 构建方法...");}}
再次运行代码,可以看到这次就是DbConfig1先加载
4.2 @AutoConfigureOrder 操作演示
也可以使用AutoConfigureOrder 注解来控制不同配置类的加载顺序,数字越小,优先顺序越高,添加两个配置类,分别使用该注解进行标注
@Configuration
@AutoConfigureOrder(2)
public class OrderConfig1 {public OrderConfig1(){System.out.println("OrderConfig1 加载...");}
}
OrderConfig2中的数值更大,理论上OrderConfig1优先加载
@Configuration
@AutoConfigureOrder(7)
public class OrderConfig2 {public OrderConfig2(){System.out.println("OrderConfig2 加载...");}
}
同样,使用AutoConfigureOrder控制配置类的加载顺序也需要将其配置到spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.congge.config.DbConfig2,\
com.congge.config.DbConfig1,\
com.congge.config.OrderConfig1,\
com.congge.config.OrderConfig2
运行上面的代码,看到如下效果,说明OrderConfig1优于OrderConfig2加载
4.3 源码解读与分析
最关键的代码在AutoConfigurationImportSelector这个类中,spring在bean装载过程中,将自动配置类从spring.factories加载出来之后会根据条件排序,在selectImports()方法中最后一行代码进行排序,如下
跟进sortAutoConfigurations这个方法,最终的排序逻辑来到下面这个getInPriorityOrder方法中;
在这个方法中,关于排序是分成3种方式完成的
- 先按字母排序;
- 再按照@AutoConfigureOrder进行排序;
- 最后按照 @AutoConfigureBefore和@AutoConfigureAfter排序;
而从配置的顺序不难发现,最终决定权还是在@AutoConfigureAfter、@AutoConfigureBefore这两个注解。
五、自定义ApplicationContextInitializer
对spring的bean的生命周期和加载过程熟悉的同学,想必了解到,容器启动过程中,通过解析xml文件中的配置生成bean或者通过扫描路径并解析得到bean,这些bean最终会统一保存在一个容器中被spring管理。既然如此,开发人员就可以人工的干预这个bean的解析过程,通过spring提供的相关扩展点,改变bean在容器中的位置就可以达到控制bean的顺序了,下面看具体的操作流程。
5.1 ApplicationContextInitializer介绍
先看spring官网的介绍:
翻译过来大概的意思如下
- 用于在spring容器刷新之前初始化Spring ConfigurableApplicationContext的回调接口。(剪短说就是在容器刷新之前调用该类的 initialize 方法。并将 ConfigurableApplicationContext 类的实例传递给该方法);
- 通常用于需要对应用程序上下文进行编程初始化的web应用程序中。例如,根据上下文环境注册属性源或激活配置文件等;
- 可排序的(实现Ordered接口,或者添加@Order注解);
5.2 ApplicationContextInitializer使用
新建一个类 MyAppInitializer并实现 ApplicationContextInitializer 接口
public class MyAppInitializer implements ApplicationContextInitializer {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("-----MyAppInitializer initialize-----");}
}
然后在启动类中添加进去
@SpringBootApplication
public class BootApp {public static void main(String[] args) {SpringApplication application = new SpringApplication(BootApp.class);application.addInitializers(new MyAppInitializer());application.run(args);}
}
运行上面的main程序,在启动时看到控制台输出下面的信息
从上面的介绍了解到,实现ApplicationContextInitializer该接口,将会在容器刷新之前进行加载,对应到spring源码中,即refreshContext(context)方法,了解spring的bean的加载流程的同学应该知道,refreshContext里面就是调用AbstractApplicationContext的refresh的方法,其主要功能就是注册spring容器里面的bean,以及对bean的处理还有广播等功能,简而言之,就是在这个方法中,完成系统中bean的创建和存储的一系列过程。
基于此,按照上面的效果来看,实现ApplicationContextInitializer该接口之后,其类的加载时机要更加靠前,于是就可以借助这个特性,在bean还没有真正创建出来之前,人为的干预bean的创建顺序,将指定的类注册到spring上下文中。
5.3 ApplicationContextInitializer控制加载顺序
自定义一个类实现ApplicationContextInitializer接口
public class MyAppInitializer implements ApplicationContextInitializer {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {System.out.println("-----MyAppInitializer initialize-----");applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());}
}
自定义一个类实现接口BeanDefinitionRegistryPostProcessor,重写postProcessBeanDefinitionRegistry方法,手动注册需要控制加载到容器中顺序的类,注意,按照上面的流程操作完成之后,对于你要控制的配置类,就不要使用相关的注解标注了,比如下面要控制的是OrderService这个类的顺序在最前面。
public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();beanDefinition.setBeanClass(OrderService.class);beanDefinitionRegistry.registerBeanDefinition("orderService",beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}
将MyAppInitializer配置到spring.factories文件中
org.springframework.context.ApplicationContextInitializer=\
com.congge.config.MyAppInitializer
运行main程序,观察控制台输出效果如下,说明OrderService不仅被容器管理,而且顺序在最前面,这就达到了控制bean的顺序的目的。
六、使用场景
到这里,再来看文章开头提出的问题,为什么需要控制spring中bean的加载顺序呢?关于这个问题,这里提出下面的几种常用的场景。
6.1 解决bean的依赖关系
比如在初始化时,配置类B需要用到配置类A中的某些属性,配置类C需要用到B中的某些属性,在这种级联依赖的情形下,为了避免启动过程中依赖的问题导致启动失败,就可以通过控制配置bean的顺序来解决。
6.2 设置某些配置类的优先级最高
比如说,我们有一个商品管理的配置类,需要在项目启动的时候,完成从数据库的数据写入到redis缓存中,并且定时刷新商品数据,并且该类还提供了一个对外访问的static方法,这种场景下,由于对外提供了static方法,其他类可以直接调用它的方法,如果不是最先加载的话,当请求获取商品数据时,商品还没有加载完成,那就就会出现问题。因此就需要保证这个配置bean最先被加载。
6.3 依赖传递
当程序中需要对接口的参数进行不同梯度的校验和拦截时,一个常见的做法就是利用AOP,减少对主业务流程的干扰,在这种情况下,如果在A类的AOP逻辑处理完成之后继续传递到下一级B的AOP中进行处理,这就需要控制不同的AOP类的执行顺序,这时就需要控制不同AOP的执行顺序。
七、写在文末
在某些特殊的业务场景下,合理控制bean的加载顺序可以帮助我们解决很多复杂的业务需求,同时也可以作为spring提供的一种功能扩展点进行使用,在spring体系中具有重要的作用,本篇到此结束,感谢观看。
相关文章:
【微服务】spring 控制bean加载顺序使用详解
目录 一、前言 二、使用order注解控制顺序 2.1 order 注解使用示例 2.2 order注解顺序失效问题 2.2.1 order失效问题解决办法 2.3 实现Ordered接口 三、使用dependon注解控制顺序 四、AutoConfiguration注解控制bean加载顺序 4.1 AutoConfigureBefore 操作演示 4.2 A…...
python-切换镜像源和使用PyCharm进行第三方开源包安装
文章目录 前言python-切换镜像源和使用PyCharm进行第三方开源包安装1. 切换镜像源2. 使用PyCharm进行第三方开源包安装 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每…...
tp6 + swagger 配置文档接口
ThinkPHP 6.0 运行环境要求PHP7.2,兼容PHP8.1 安装 composer create-project topthink/think tp 6.0.*如果需要更新框架使用 composer update topthink/framework文档 完全开发手册 swagger 文档 注解文档 安装包 composer require zircote/swagger-php 引用…...
试图一文彻底讲清 “精准测试”
在软件测试中,我们常常碰到两个基本问题(困难): 很难保障无漏测:我们做了大量测试,但不清楚测得怎样,对软件上线后会不会出问题,没有信心; 选择待执行的测试用例&#…...
Visual Studio 删除行尾空格
1.CtrlH 打开替换窗口(注意选择合适的查找范围) VS2010: VS2017、VS2022: 2.复制下面正则表达式到上面的选择窗口(注意前面有一个空格): VS2010: $ VS2017、VS2022: $ 3.下面的替换窗口不写入 VS2010: VS2017、VS2022: 4.点选“正则表达式…...
LeetCode_BFS_中等_1926.迷宫中离入口最近的出口
目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个 m x n 的迷宫矩阵 maze (下标从 0 开始),矩阵中有空格子(用 ‘.’ 表示)和墙(用 ‘’ 表示)。同时给你迷宫的入口 …...
开源Windows12网页版HTML源码
开源Windows12网页版HTML源码,无需安装就能用的Win12网页版来了Windows12概念版(PoweredbyPowerPoint)后深受启发,于是通过使用HTML、CSS、js等技术做了这样一个模拟板的Windows12系统,并已发布至github进行开源。 这…...
vscode中使用指定路径下的cmake
在 Visual Studio Code 中指定自定义的 CMake 路径,你可以通过以下步骤来实现: 打开你的 CMake 项目所在的文件夹,在 Visual Studio Code 中。 在项目文件夹中,创建一个名为 .vscode 的文件夹,如果它还不存在。 在 .…...
复杂度分析
文章目录 如何分析、统计算法的执行效率和资源消耗?为什么需要复杂度分析?测试结果非常依赖测试环境测试结果受数据规模的影响很大 大O复杂度表示法时间复杂度分析只关注循环次数最多的一段代码加法法则:总复杂度等于量级最大的那段代码的复杂…...
Linux安装jrockit-jdk1.6.0_29-R28.2.0-4.1.0-linux-x64
下载软件:jrockit-jdk1.6.0_29-R28.2.0-4.1.0-linux-x64.bin 执行安装 ./jrockit-jdk1.6.0_29-R28.2.0-4.1.0-linux-x64.bin 安装提示,一路next,注意第二步修改安装的路径,请修改成: <------------------------ O…...
7.2 怎样定义函数
7.2.1 为什么要定义函数 主要内容: 为什么要定义函数 C语言要求所有在程序中用到的函数必须“先定义,后使用”。这是因为在调用一个函数之前,编译系统需要知道这个函数的名字、返回值类型、功能以及参数的个数与类型。如果没有事先定义&…...
Chrome扩展V2到V3的变化
Chrome扩展manifest V3变化、升级迁移指南_chrome_ZK645945-华为云开发者联盟 (csdn.net) 1.background //V2 "background": "background.js"//V3 "background": {"service_worker": "background.js"} 2.executeScript …...
lock、tryLock、lockInterruptibly有什么区别?
lock、tryLock 和 lockInterruptibly 都是用于线程同步的方法,但它们有不同的行为和用途: lock() 方法:lock() 方法是 Java 中 Lock 接口定义的一部分,它用于获取锁并阻塞当前线程,直到锁可用为止。如果锁当前被其他线程占用,lock() 方法会导致当前线程阻塞,直到锁被释放…...
mysql面试题5:索引、主键、唯一索引、联合索引的区别?什么情况下设置了索引但无法使用?并且举例说明
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说索引、主键、唯一索引、联合索引的区别? 索引、主键、唯一索引和联合索引是数据库中常用的索引类型,它们有以下区别: 索引:索引是一种数…...
数据集笔记:纽约花旗共享单车od数据
花旗共享单车公布的其共享单车轨迹数据,包括2013年-2021年曼哈顿、布鲁克林、皇后区和泽西城大约14500辆自行车和950个站点的共享单车轨迹数据 数据地址:Citi Bike System Data | Citi Bike NYC | Citi Bike NYC 性别(0未知;1男&…...
为什么 0.1+0.2 不等于 0.3
为什么 0.10.2 不等于 0.3 在 JavaScript 中,0.1 0.2 的结果不等于 0.3,这是因为在 JavaScript 中采用的是双精度浮点数格式(64 位),而在这种格式下无法精确表示某些小数,因此在进行计算时会出现精度误差。…...
huggingface_hub v0.17 现已发布
InferenceClient 现在支持所有任务!💥,感谢社区的巨大努力,新添加的任务包括: 对象检测文本分类Token 分类翻译问题回答表格问题回答填充掩码表格分类表格回归文档问题回答视觉问题回答零样本分类 这些方法还支持使用 …...
机器学习——一元线性回归构造直线,并给出损失函数
目 录 Question 问题分析 1.概念补充 2.流程分析 3.注意 具体实现 最终成果 代码 思考: Question 在二维平面有n个点,如何画一条直线,使得所有点到该直线距离之和最短 如果能找到,请给出其损失函数 问题分析 1.概念…...
OpenHarmony自定义组件介绍
一、创建自定义组件 在ArkUI中,UI显示的内容均为组件,由框架直接提供的称为系统组件,由开发者定义的称为自定义组件。在进行 UI 界面开发时,通常不是简单的将系统组件进行组合使用,而是需要考虑代码可复用性、业务逻辑…...
云原生之使用Docker部署PDF多功能工具Stirling-PDF
云原生之使用Docker部署PDF多功能工具Stirling-PDF 一、Stirling-PDF介绍1.1 Stirling-PDF简介1.2 Stirling-PDF功能 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载Stirli…...
B树和B+树的介绍和对比,以及MySQL为何选择B+树
在计算机科学中,B树和B树是常用的数据结构,用于在大规模数据集上进行高效的插入、删除和查找操作。它们在数据库管理系统、文件系统等许多实际应用中发挥着重要作用。本文将深入介绍B树和B树的结构特点、实际应用方面以及它们的优缺点,并最后…...
MD5 绕过第一式:弱比较绕过
文章目录 参考环境MD5韧性脆弱性md5() 隐式类型转换字符串连接数学运算布尔判断相等运算符 科学计数法科学计数法前缀 0E 与 0e PHP8 与 PHP 其他版本下字符串转化为数值的具体规则PHP8数值字符串优化 其他版本更为详细的讲解 字符串与字符串的弱比较字符串与数值的弱比较0e215…...
红黑树是如何实现的?
文章目录 一、红黑树的概念二、红黑树的性质三、红黑树和AVL树对比四、红黑树的插入1. 红黑树的结点定义2. 父亲的颜色3. 叔叔的颜色为红色4. 叔叔不存在5. 叔叔存在且为黑6. 插入的抽象图 五、红黑树的验证1. 检查平衡2. 计算高度与旋转次数3. 验证 六、 红黑树与AVL树的比较 …...
实验室没人导该怎么办
实验室没人教该怎么办 Q: 国内top5高校研一,课题开始老板就给了一个大方向,之后怎么做实验都是自己看文献研究的,终于开始动手做实验,才发现别人根本不想管你,宁愿抱着电脑看剧也不想教你,十分焦虑,该怎么办? A: 按照大多数实验室的惯例,老板一定会指派一个小老板…...
pytest简明教程
1. 简介 pytest是一款基于Python的测试框架。与Python自带的unittest相比,pytes语法更加简洁,断言更加强大,并且在自动测试以及插件生态上比unittest都要更加强大。 1.1. 安装pytest pip install pytest1.2. pytest命名规则 pytest默认会…...
解决方案:解决https页面加载http资源报错
HTTPS页面加载HTTP资源会报错的原因是出于安全性考虑。 HTTPS(HyperText Transfer Protocol Secure)是一种通过使用SSL/TLS加密通信来保护数据传输的协议,它确保了客户端和服务器之间的安全连接。 当HTTPS页面尝试加载非加密的HTTP资源时&a…...
嵌入式开源库之libmodbus学习笔记
socat 安装sudo apt-get install socat创建终端 socat -d -d pty,b115200 pty,b115200查看终端 ls /dev/pts/ minicom 安装 sudo apt-get install minicom链接虚拟终端 sudo minicom -D /dev/pts/3以十六进制显示 minicom -D /dev/pts/1 -H设置波特率 minicom -D /dev/pts/1…...
Spring MVC 中的数据验证技术
一、前言 在Web开发中,数据验证是不可或缺的一部分。Spring MVC 框架提供了强大的数据验证支持,可以帮助我们轻松地对用户提交的数据进行验证。 二、实现 Spring MVC 使用 JSR-303 验证规范(Hibernate Validator 是其参考实现)…...
windows 修改hosts映射,可以ping通,但是无法通过http url 路径访问,出现 500 Internal Privoxy Error
问题描述 今天在学习nginx时,想在hosts配置一个nginx的域名映射,但是发现访问nginx服务的ip时可以访问通,在dos命令窗口ping配置的域名映射也可以ping通,但是一旦在浏览器通过http请求访问配置的hosts域名映射时却出现 500 Inter…...
如何将图片转为ico格式
这里主要是记录一个网站,如果你有更好的办法欢迎留言~ ico简介 ICO(Icon)是一种用于表示图标的文件格式,常用于Windows操作系统中。ICO格式的图片通常用于表示应用程序、文件夹、网站等的图标。 ICO文件可以包含多个图标&#x…...
网站如何做百度权重/图片搜索图片识别
题目 长度为n(n<3e5)的数组,q(q<3e5)次操作,操作分两种, 1. 输入i x(x<1e9),将ai改成x 2. 输入l r k(1<k<n),询问对于在[l,r]内出现的每种数,其在[l,r]内的出现次数是不是均为k的倍数 思…...
求大神帮忙做网站/搜索引擎营销有哪些
JavaScript For 循环循环在编程中用于自动执行重复性任务。例如,假设我们要打印“ Hello World” 10次。可以如下所示进行:document.write("Hello World");document.write("Hello World");document.write("Hello World");…...
网站会员收费怎么做/googlechrome
拦截器的实现原理很简单,就是动态代理,实现AOP机制。当外部调用被拦截bean的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作。 但是最近在项目中要在一个事务中…...
新闻宣传wordpress主题/如何优化关键词提升相关度
在安装之前,确认你的机器安装了python,和easy_install.通常python是自动安装的,如果没有安装easy_install,那么wget -q http://peak.telecommunity.com/dist/ez_setup.py获取一下python ez_setup.pypexpect是python一个模块,可以通…...
达州做网站的公司/自己创建网页
前言 在做winform项目的时候有时候会用到复制粘贴,在.net中提供了Clipboard类来操作剪切板,我们来看下。 clipbrd.exe clipbrd是系统剪切板程序,但是在vista及以上程序不提供,我们需要网上下载一个并复制到System32目录下。 直接在…...
那些网站做汽车可靠性/站长之家ping检测
通过log打印出来的信息很快就一闪而过了,着实很郁闷。这里通过更改logcat的缓存数解决的,eclipse默认是5000,我将其改成了50000。 转载于:https://www.cnblogs.com/xiaofeng6636/p/4931913.html...