Springboot中为Kafka提供了一个自动配置类 KafkaAutoConfiguration 在KafkaAutoConfiguration类上有一个注解: @ConditionalOnClass...Retention(RetentionPolicy.RUNTIME) @Documented @Conditional(OnClassCondition.class) public @interface ConditionalOnClass...* @return the class names that must be present. */ String[] name() default {}; } @ConditionalOnClass...其他类似注解: @ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean) @ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean
Spring Boot实现了很多有用的条件注入,其中ConditionalOnClass的实现让人感到困惑,因为如果类不存在的话,加载就会抛出错误NoClassDefFoundError。...其实Spring Boot使用的字节码技术来实现这一点的 实现原理 Spring在加载类之前,会提前使用字节码技术来读取这个类(并没有使用ClassLoader),然后解析里面的ConditionalOnClass
- Bean method 'cachingLBClientFactory' in 'FeignRibbonClientAutoConfiguration' not loaded because @ConditionalOnClass...method 'retryabeCachingLBClientFactory' in 'FeignRibbonClientAutoConfiguration' not loaded because @ConditionalOnClass
还提供了更多简化的注解使用方式,省略了自己实现Condtion接口,本篇博文主要介绍下面几个常用的注解使用方式 @ConditionalOnBean @ConditionalOnMissingBean @ConditionalOnClass...@ConditionalOnClass 要求class存在 a. 注解定义 public @interface ConditionalOnClass { Class<?...接下来就是Bean的配置 /** * 当引用了 {@link DependedClz} 类之后,才会创建bean: `LoadIfClzExists` * * @return */ @Bean @ConditionalOnClass...基础篇Bean之动态注册 181018-SpringBoot基础篇Bean之条件注入@Condition使用姿势 181019-SpringBoot基础篇Bean之@ConditionalOnBean与@ConditionalOnClass
比如: @ConditionalOnBean、 @ConditionalOnClass、 @ConditionalOnExpression、 @ConditionalOnMissingBean等。...比如@ConditionalOnClass会检查类加载器中是否存在对应的类,如果有的话被注解修饰的类就有资格被Spring容器所注册,否则会被skip。...比如FreemarkerAutoConfiguration这个自动化配置类的定义如下: @Configuration @ConditionalOnClass({ freemarker.template.Configuration.class...) @Documented @Conditional(OnClassCondition.class) public @interface ConditionalOnClass { Class<?...); // 得到@ConditionalOnClass注解的属性 if (onClasses !
spring.aop.proxy-target-class=true) matched (OnPropertyCondition) DispatcherServletAutoConfiguration matched: - @ConditionalOnClass...OnWebApplicationCondition) DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched: - @ConditionalOnClass...Negative matches: ----------------- ActiveMQAutoConfiguration: Did not match: - @ConditionalOnClass...OnClassCondition) AopAutoConfiguration.AspectJAutoProxyingConfiguration: Did not match: - @ConditionalOnClass...org.aspectj.weaver.Advice' (OnClassCondition) ArtemisAutoConfiguration: Did not match: - @ConditionalOnClass
再来看看数据源自动配置的实现注解 @Configuration @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })...@Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。...================== Positive matches: ----------------- AopAutoConfiguration matched: - @ConditionalOnClass...EnvAutoConfig matched: - @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver...Negative matches: ----------------- ActiveMQAutoConfiguration: Did not match: - @ConditionalOnClass
/** * Nested configuration if Jetty is being used. */ @Configuration @ConditionalOnClass... /** * Nested configuration if Undertow is being used. */ @Configuration @ConditionalOnClass...@ConditionalOnClass({ Servlet.class, Tomcat.class }) 表示有使用类Tomcat.class则是tomcat容器 2、Jetty容器 Java代码 ...@ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })...@ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class }) ===================
,如果各种字符集的实现都有第三方来做,那么在制作一个通用的starter时,就会有class不在classpath下的情况,那么就会用到@ConditionalOnClass的注解来判断是否在classpath...但本人在制作starter时,最初是把@ConditionalOnClass注解加入到方法上,这样就可以一个XXXAutoConfiguration类注入很多实现该接口的服务,但实际往往与理想相悖。...通过测试发现@ConditionalOnClass在类上面是可以实现classpath下类是否存在的检测的,如果不存在,则不注入,如果存在,则进行相关的注入操作,但为什么@ConditionalOnClass...通过对Spring Boot org.springframework.boot.autoconfigure包中源码的阅读,得知 SpringBoot 其实也是只是把@ConditionalOnClass...注解,那么最好的解决办法就是像这样写一些静态内部类,然后再把公共类进行自动注入,这样,当加载公共类时,就会去加载这些静态的内部类,然后就会根据@ConditionalOnClass的条件,是否进行自动注入了
ApolloRefreshProperties.class}) public class ApolloRefreshAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnClass...因为他们大部分业务都跑在jdk8,冒然升级成jdk11,也不知道会不会因为了解决一个问题,而引入其他问题 2 问题排查 因为这个starter的自动装配配置的内容相对简单,基于老司机的第六感,问题大概率是出现在@ConditionalOnClass...这注解上,于是点开@ConditionalOnClass,他的注解上有如下提示 他的大意是,可以在@Configuration classes上安全地指定value(),因为在加载类之前会使用ASM...如果非要用方法注解,建议使用ConditionalOnClass里面的name字段 于是我们听官方的建议,将starter调整如下 @Configuration @EnableConfigurationProperties...spring-projects/spring-boot/issues/27846 https://github.com/spring-projects/spring-boot/issues/17282 3 总结 首先如果用 @ConditionalOnClass
ApolloRefreshProperties.class})public class ApolloRefreshAutoConfiguration { @Bean @ConditionalOnMissingBean @ConditionalOnClass...因为他们大部分业务都跑在jdk8,冒然升级成jdk11,也不知道会不会因为了解决一个问题,而引入其他问题问题排查因为这个starter的自动装配配置的内容相对简单,基于老司机的第六感,问题大概率是出现在@ConditionalOnClass...这注解上,于是点开@ConditionalOnClass,他的注解上有如下提示图片他的大意是,可以在@Configuration classes上安全地指定value(),因为在加载类之前会使用ASM解析注释元数据...如果非要用方法注解,建议使用ConditionalOnClass里面的name字段于是我们听官方的建议,将starter调整如下@Configuration@EnableConfigurationProperties...spring-projects/spring-boot/issues/27846https://github.com/spring-projects/spring-boot/issues/17282总结首先如果用 @ConditionalOnClass
LoadBalancerClient loadBalancerClient() { return new RibbonLoadBalancerClient(springClientFactory()); } @Bean @ConditionalOnClass...AllNestedConditions { RibbonClassesConditions() { super(ConfigurationPhase.PARSE_CONFIGURATION); } @ConditionalOnClass...(IClient.class) static class IClientPresent { } @ConditionalOnClass(RestTemplate.class) static class...RestTemplatePresent { } @ConditionalOnClass(AsyncRestTemplate.class) static class AsyncRestTemplatePresent...{ } @ConditionalOnClass(Ribbon.class) static class RibbonPresent { } } } RibbonAutoConfiguration
方法返回值为true时,才会进入该方法创建bean"); return ""; } /** * 该Abc class位于类路径上时 */ @ConditionalOnClass...(Abc.class) @Bean public String abc() { System.err.println("ConditionalOnClass true")...; return ""; } // @ConditionalOnClass(Abc.class) // @Bean // public Abc newAbc(...) { // System.err.println("ConditionalOnClass true"); // return new Abc(); // }...Configuration @ConditionalOnProperty( value = {"abc.property"}, matchIfMissing = false ) @ConditionalOnClass
org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass...EmbeddedWebServerFactoryCustomizerAutoConfiguration { /** * Nested configuration if Tomcat is being used. */ @Configuration @ConditionalOnClass...} } /** * Nested configuration if Jetty is being used. */ @Configuration @ConditionalOnClass...} } /** * Nested configuration if Undertow is being used. */ @Configuration @ConditionalOnClass...} } /** * Nested configuration if Netty is being used. */ @Configuration @ConditionalOnClass
springClientFactory(), ribbonEagerLoadProperties.getClients()); } @Configuration @ConditionalOnClass...RibbonClassesConditions() { super(ConfigurationPhase.PARSE_CONFIGURATION); } @ConditionalOnClass...(IClient.class) static class IClientPresent { } @ConditionalOnClass(RestTemplate.class...) static class RestTemplatePresent { } @ConditionalOnClass(AsyncRestTemplate.class...) static class AsyncRestTemplatePresent { } @ConditionalOnClass(Ribbon.class
`@ConditionalOnClass` 2. `@ConditionalOnProperty` 3....Spring提供了一些内置的条件注解,如@ConditionalOnClass、@ConditionalOnProperty、@ConditionalOnWebApplication等。...@ConditionalOnClass @ConditionalOnClass注解允许您根据类的存在与否来条件加载Bean。例如,如果您希望在类路径中存在某个特定类时加载Bean,可以使用该注解。...@Configuration @ConditionalOnClass(name = "com.example.SomeClass") public class MyConfiguration {...Spring提供了许多内置的条件注解,如@ConditionalOnClass、@ConditionalOnProperty等,同时也支持创建自定义的条件注解。
>[] value() default {}; String[] name() default {}; } 可以看到, @ConditionalOnClass 注解本身带有两个属性,一个 Class...同时 ConditionalOnClass 注解本身还带了一个 @Conditional(OnClassCondition.class) 注解。...所以, ConditionalOnClass 注解的判断条件其实就包含在 OnClassCondition 这个类中。...这里的 getClassOrMethodName 方法获取被添加了@ConditionalOnClass 注解的类或者方法的名称,而 getMatchOutcome 方法用于获取匹配的输出。...首先通过 getCandidates 方法获取了 ConditionalOnClass 的 name 属性和 value 属性。
= null) { String candidates = autoConfigurationMetadata.get(autoConfigurationClass, "ConditionalOnClass...AutoConfigurationMetadata 接口的 get(String className, String key) 方法来获取与autoConfigurationClass 关联的名为 "ConditionalOnClass...missing.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class...missing.isEmpty()) { return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class...matchMessage = matchMessage.andCondition(ConditionalOnClass.class) .found("required class", "required
领取专属 10元无门槛券
手把手带您无忧上云