SpringBoot的@Conditional和自动配置类生效
@Conditional原理
在之前的博客中提到了关于自动配置的原理,但是在自动配置的时候有很多的判断,只有当这些判断都成功之后在自动配置的时候才会成功。但是我们会发现一个问题,当我们使用@Bean注解往容器中添加组件的时候也会有很多的判断。这里我们还是以HttpEncodingAutoConfiguration自动注解来说。在HttpEncodingAutoConfiguration类中有这样的的一个注解@ConditionalOnMissingBean,这个注解表示当没有后面的类的时候才会将这个组件注入到容器中。
@Bean@ConditionalOnMissingBean(CharacterEncodingFilter.class)public CharacterEncodingFilter characterEncodingFilter() {CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();filter.setEncoding(this.properties.getCharset().name());filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));return filter;}
查看HttpEncodingAutoConfiguration的源码会发现在这个类中有很多的以@ConditionalOnXXX注解,而进入这写注解之后,我们会发现它的底层就是使用我们Spring的@Conditional而在使用这个注解的时候会发现这个注解后面会跟上一个类。我们查看这个类的源码。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
这一段就是我们看到的OnClassCondition类的源码中的一部分。当条件判断失败的时候就会返回false,这个时候就回到上一层级,也就是组件的注入。也就是当判断不成功的时候就会执行组件注入的操作。
public boolean[] match(String[] autoConfigurationClasses,AutoConfigurationMetadata autoConfigurationMetadata) {ConditionEvaluationReport report = getConditionEvaluationReport();ConditionOutcome[] outcomes = getOutcomes(autoConfigurationClasses,autoConfigurationMetadata);boolean[] match = new boolean[outcomes.length];for (int i = 0; i < outcomes.length; i++) {match[i] = (outcomes[i] == null || outcomes[i].isMatch());if (!match[i] && outcomes[i] != null) {logOutcome(autoConfigurationClasses[i], outcomes[i]);if (report != null) {report.recordConditionEvaluation(autoConfigurationClasses[i], this,outcomes[i]);}}}return match;}
而对于原生的@Conditional注解在Spring的注解使用的时候都是可以用到的。而在SpringBoot中的作用就是:当这个注解指定的条件成立的时候,才可以给容器中添加组件,自动配置里面的内容才会生效。
当然SpringBoot中对这个注解也是做了很多的扩展
@Conditional扩展注解 | 作用(判断当前条件是否满足) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中是否存在指定的Bean |
@ConditionalOnMissingBean | 容器中不存在指定的类 |
@ConditionalOnExpression | 满足SpEL表达式指定规范 |
@ConditionalOnClass | 在系统中有指定的对应的类 |
@ConditionalOnMissingClass | 在系统中没有指定对应的类 |
@ConditionalOnSingleCandidate | 容器中是否指定一个单实例的Bean,或者找个是一个首选的Bean |
@ConditionalOnProperty | 系统中指定的对应的属性是否有对应的值 |
@ConditionalOnResource | 类路径下是否存在指定的资源文件 |
@ConditionalOnWebApplication | 当前是Web环境 |
@ConditionalOnNotWebApplication | 当前不是Web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
当然除了上面这些还有很多的其他的应用,就需要在使用的时候进行自己的扩展开发。
自动配置类生效
自动配置类必须在一定的条件下才能生效使用,虽然在SpringBoot中加载了很多的自动配置,但是并不是每个自动配置类都会生效,但是在使用的时候需要在一定条件下才会生效,这个就需要通过使用这些判断条件来实现。例如下面的Spring经典AOP概念
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {@Configuration@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)public static class JdkDynamicAutoProxyConfiguration {}@Configuration@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)public static class CglibAutoProxyConfiguration {}}
在上面我们看到要想使的AOP的自动配置生效就需要有如下的判断
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
这个就表示在这个自动配置中需要有后面括号中的三个类,
在上面的配置中并没有引入对应的Aspect类和Advice类,这个就表示这个自动注解是不可用的。
而现在一个比较重要的事情就是怎么知道哪些自动配置类生效,我们也看到了在配置文件中有很多的自动配置类,但是如果使用之前的这种方式一个个的分析配置类的话就会花费很多的时间。下面就来看一下通过SpringBoot的debug模式实现这样的判断。
debug=true
一旦使用Debug模式启动时候,控制台就会打印出对应的那些配置类被加载了。而这就是生效的类。在启动报告中有两个部分一部分是Positive matches另一部分是Negative matches
以下就是控制台打印出来的Positive matches信息,自动加载了很多的配置类。还有就是第二部分Negative matches。这里只是展示了Positive部分。
DispatcherServletAutoConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration matched:- @ConditionalOnClass found required class 'javax.servlet.ServletRegistration'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- DispatcherServlet Registration did not find servlet registration bean (DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition)DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration#dispatcherServletRegistration matched:- @ConditionalOnBean (names: dispatcherServlet; types: org.springframework.web.servlet.DispatcherServlet; SearchStrategy: all) found beans 'dispatcherServlet', 'dispatcherServlet' (OnBeanCondition)EmbeddedServletContainerAutoConfiguration matched:- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)EmbeddedServletContainerAutoConfiguration.EmbeddedTomcat matched:- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.apache.catalina.startup.Tomcat'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnMissingBean (types: org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; SearchStrategy: current) did not find any beans (OnBeanCondition)ErrorMvcAutoConfiguration matched:- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)ErrorMvcAutoConfiguration#basicErrorController matched:- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)ErrorMvcAutoConfiguration#errorAttributes matched:- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorAttributes; SearchStrategy: current) did not find any beans (OnBeanCondition)ErrorMvcAutoConfiguration.DefaultErrorViewResolverConfiguration#conventionErrorViewResolver matched:- @ConditionalOnBean (types: org.springframework.web.servlet.DispatcherServlet; SearchStrategy: all) found bean 'dispatcherServlet'; @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.DefaultErrorViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration matched:- @ConditionalOnProperty (server.error.whitelabel.enabled) matched (OnPropertyCondition)- ErrorTemplate Missing did not find error template view (ErrorMvcAutoConfiguration.ErrorTemplateMissingCondition)ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration#beanNameViewResolver matched:- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.BeanNameViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)ErrorMvcAutoConfiguration.WhitelabelErrorViewConfiguration#defaultErrorView matched:- @ConditionalOnMissingBean (names: error; SearchStrategy: all) did not find any beans (OnBeanCondition)GenericCacheConfiguration matched:- Cache org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration automatic cache type (CacheCondition)HttpEncodingAutoConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.web.filter.CharacterEncodingFilter'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)- @ConditionalOnProperty (spring.http.encoding.enabled) matched (OnPropertyCondition)HttpEncodingAutoConfiguration#characterEncodingFilter matched:- @ConditionalOnMissingBean (types: org.springframework.web.filter.CharacterEncodingFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)HttpMessageConvertersAutoConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.http.converter.HttpMessageConverter'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)HttpMessageConvertersAutoConfiguration#messageConverters matched:- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.HttpMessageConverters; SearchStrategy: all) did not find any beans (OnBeanCondition)HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.http.converter.StringHttpMessageConverter'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)HttpMessageConvertersAutoConfiguration.StringHttpMessageConverterConfiguration#stringHttpMessageConverter matched:- @ConditionalOnMissingBean (types: org.springframework.http.converter.StringHttpMessageConverter; SearchStrategy: all) did not find any beans (OnBeanCondition)JacksonAutoConfiguration matched:- @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)JacksonAutoConfiguration.Jackson2ObjectMapperBuilderCustomizerConfiguration matched:- @ConditionalOnClass found required classes 'com.fasterxml.jackson.databind.ObjectMapper', 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration matched:- @ConditionalOnClass found required classes 'com.fasterxml.jackson.databind.ObjectMapper', 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)JacksonAutoConfiguration.JacksonObjectMapperBuilderConfiguration#jacksonObjectMapperBuilder matched:- @ConditionalOnMissingBean (types: org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition)JacksonAutoConfiguration.JacksonObjectMapperConfiguration matched:- @ConditionalOnClass found required classes 'com.fasterxml.jackson.databind.ObjectMapper', 'org.springframework.http.converter.json.Jackson2ObjectMapperBuilder'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)JacksonAutoConfiguration.JacksonObjectMapperConfiguration#jacksonObjectMapper matched:- @ConditionalOnMissingBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) did not find any beans (OnBeanCondition)JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration matched:- @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnProperty (spring.http.converters.preferred-json-mapper=jackson) matched (OnPropertyCondition)- @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean 'jacksonObjectMapper' (OnBeanCondition)JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration#mappingJackson2HttpMessageConverter matched:- @ConditionalOnMissingBean (types: org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; SearchStrategy: all) did not find any beans (OnBeanCondition)JmxAutoConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.jmx.export.MBeanExporter'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnProperty (spring.jmx.enabled=true) matched (OnPropertyCondition)JmxAutoConfiguration#mbeanExporter matched:- @ConditionalOnMissingBean (types: org.springframework.jmx.export.MBeanExporter; SearchStrategy: current) did not find any beans (OnBeanCondition)JmxAutoConfiguration#mbeanServer matched:- @ConditionalOnMissingBean (types: javax.management.MBeanServer; SearchStrategy: all) did not find any beans (OnBeanCondition)JmxAutoConfiguration#objectNamingStrategy matched:- @ConditionalOnMissingBean (types: org.springframework.jmx.export.naming.ObjectNamingStrategy; SearchStrategy: current) did not find any beans (OnBeanCondition)MultipartAutoConfiguration matched:- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.multipart.support.StandardServletMultipartResolver', 'javax.servlet.MultipartConfigElement'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnProperty (spring.http.multipart.enabled) matched (OnPropertyCondition)MultipartAutoConfiguration#multipartConfigElement matched:- @ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement,org.springframework.web.multipart.commons.CommonsMultipartResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)MultipartAutoConfiguration#multipartResolver matched:- @ConditionalOnMissingBean (types: org.springframework.web.multipart.MultipartResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)NoOpCacheConfiguration matched:- Cache org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration automatic cache type (CacheCondition)PropertyPlaceholderAutoConfiguration#propertySourcesPlaceholderConfigurer matched:- @ConditionalOnMissingBean (types: org.springframework.context.support.PropertySourcesPlaceholderConfigurer; SearchStrategy: current) did not find any beans (OnBeanCondition)RedisCacheConfiguration matched:- Cache org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration automatic cache type (CacheCondition)ServerPropertiesAutoConfiguration matched:- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)ServerPropertiesAutoConfiguration#serverProperties matched:- @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ServerProperties; SearchStrategy: current) did not find any beans (OnBeanCondition)SimpleCacheConfiguration matched:- Cache org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration automatic cache type (CacheCondition)SpringApplicationAdminJmxAutoConfiguration matched:- @ConditionalOnProperty (spring.application.admin.enabled=true) matched (OnPropertyCondition)SpringApplicationAdminJmxAutoConfiguration#springApplicationAdminRegistrar matched:- @ConditionalOnMissingBean (types: org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar; SearchStrategy: all) did not find any beans (OnBeanCondition)ValidationAutoConfiguration matched:- @ConditionalOnClass found required class 'javax.validation.executable.ExecutableValidator'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnResource found location classpath:META-INF/services/javax.validation.spi.ValidationProvider (OnResourceCondition)ValidationAutoConfiguration#defaultValidator matched:- @ConditionalOnMissingBean (types: javax.validation.Validator; SearchStrategy: all) did not find any beans (OnBeanCondition)ValidationAutoConfiguration#methodValidationPostProcessor matched:- @ConditionalOnMissingBean (types: org.springframework.validation.beanvalidation.MethodValidationPostProcessor; SearchStrategy: all) did not find any beans (OnBeanCondition)WebClientAutoConfiguration.RestTemplateConfiguration matched:- @ConditionalOnClass found required class 'org.springframework.web.client.RestTemplate'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)WebClientAutoConfiguration.RestTemplateConfiguration#restTemplateBuilder matched:- @ConditionalOnMissingBean (types: org.springframework.boot.web.client.RestTemplateBuilder; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration matched:- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet', 'org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)- @ConditionalOnMissingBean (types: org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration#hiddenHttpMethodFilter matched:- @ConditionalOnMissingBean (types: org.springframework.web.filter.HiddenHttpMethodFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration#httpPutFormContentFilter matched:- @ConditionalOnProperty (spring.mvc.formcontent.putfilter.enabled) matched (OnPropertyCondition)- @ConditionalOnMissingBean (types: org.springframework.web.filter.HttpPutFormContentFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#defaultViewResolver matched:- @ConditionalOnMissingBean (types: org.springframework.web.servlet.view.InternalResourceViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#requestContextFilter matched:- @ConditionalOnMissingBean (types: org.springframework.web.context.request.RequestContextListener,org.springframework.web.filter.RequestContextFilter; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#viewResolver matched:- @ConditionalOnBean (types: org.springframework.web.servlet.ViewResolver; SearchStrategy: all) found beans 'defaultViewResolver', 'beanNameViewResolver', 'mvcViewResolver'; @ConditionalOnMissingBean (names: viewResolver; types: org.springframework.web.servlet.view.ContentNegotiatingViewResolver; SearchStrategy: all) did not find any beans (OnBeanCondition)WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter.FaviconConfiguration matched:- @ConditionalOnProperty (spring.mvc.favicon.enabled) matched (OnPropertyCondition)WebSocketAutoConfiguration matched:- @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'javax.websocket.server.ServerContainer'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)- @ConditionalOnWebApplication (required) found 'session' scope (OnWebApplicationCondition)WebSocketAutoConfiguration.TomcatWebSocketConfiguration matched:- @ConditionalOnClass found required classes 'org.apache.catalina.startup.Tomcat', 'org.apache.tomcat.websocket.server.WsSci'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)WebSocketAutoConfiguration.TomcatWebSocketConfiguration#websocketContainerCustomizer matched:- @ConditionalOnJava (1.7 or newer) found 1.8 (OnJavaCondition)- @ConditionalOnMissingBean (names: websocketContainerCustomizer; SearchStrategy: all) did not find any beans (OnBeanCondition)
总结
使用自动配置的报告可以更加高效的查看出那些自动配置是生效的,那些自动配置是没有被加载,可以更高效的帮助使用者进行SpringBoot应用的开发
SpringBoot的@Conditional和自动配置类生效相关推荐
- 自动配置原理精讲||@Conditional ||怎么知道哪些自动配置类生效? 启用debug=true属性(在配置文件配置);
自动配置原理精讲 派生注解 配置文件怎么配置 server.port spring.config.location="D://application.properties" htt ...
- SpringBoot自定义Starter(自动配置类)
前言 SpringBoot其实从诞生以来围绕的核心就是快速构建项目,快速构建的前提是有人帮你做好轮子,开发者只要拿来即用就好了,而造好轮子的人就是SpringBoot的开发者,引入自动配置的形式帮助开 ...
- springboot 启动分析【难点】——如何自动扫描 @SpringBootApplication||如何加载自动配置类 @EnableAutoConfiguration||如何加载前端控制器
springboot 启动分析[难点] 自动扫描的特点 默认扫描与 启动类 同级的所有包及其子包都可以自动扫描 如果不可要使用@ComponentScan(basePackage={"&qu ...
- SpringBoot核心原理:自动配置、事件驱动、Condition
点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/l6108003/article/ details/106966386 前言 SpringBoot是Spring的包装,通过自动 ...
- java框架之SpringBoot(5)-SpringMVC的自动配置
本篇文章内容详细可参考官方文档第 29 节. SpringMVC介绍 SpringBoot 非常适合 Web 应用程序开发.可以使用嵌入式 Tomcat,Jetty,Undertow 或 Netty ...
- SpringBoot自动配置【源码分析】-初始加载自动配置类
@Import(AutoConfigurationImportSelector.class) 1.利用getAutoConfigurationEntry(annotationMetadata);给容器 ...
- springboot启动时,排除某些自动配置类
springboot在启动时会读取jar包下的spring.factories文件中的EnableAutoConfiguration为键的数据,自动加载这些类,如下图示例. 但有时候,这些自动配置的类 ...
- springboot 获取bean_SpringBoot高级(自动配置 事件监听 监控)
SpringBoot自动配置 condition-1 Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean @Conditio ...
- springboot中使用servlet通过配置类
在servlet目录下创建个servlet类,示例代码如下: package com.bjpowernode.springboot.servlet;import javax.servlet.Servl ...
最新文章
- Internet History, Technology, and Security----第三周
- 最近一直想写一个关于Installshield的连载专题
- 《剑指offer》第四十九题(丑数)
- 藏獒当初为何成为“神话”,如今是谁毁了昔日藏獒的神话?
- Synchronize对象属性改变
- 实现一个压缩Remoting传输数据的Sink:CompressionSink
- 频段表_VoLTE高低频段覆盖能力研究
- JavaWeb基础学习笔记
- WebApi和MVC的区别
- Tech·ED2007微软技术大会鲍尔默演讲实录
- $(document).ready()和onload区别
- 字节工程师薪资排世界第五,中位数 43 万美元,2021 全球程序员收入报告出炉!...
- SLAM_2019-ICCV_GSLAM:通用 SLAM 框架和基准
- steam++(GitHub加速)433端口占用解决方案
- Staring into the Abyss: An Evaluation of Concurrency Control with One Thousand Cores 论文阅读
- Java_Java多线程_Java线程池核心参数 与 手动创建线程池
- opencv HSV 颜色模型(H通道取值 CV_BGR2HSV_FULL)
- A. Chess Placing
- python制作一个网易音乐下载器
- H3C_RIP_路由器_动态路由