spring-projects / spring-boot

Spring Boot helps you to create Spring-powered, production-grade applications and services with absolute minimum fuss.
https://spring.io/projects/spring-boot
Apache License 2.0
75.02k stars 40.65k forks source link

Support early class filtering for @ConditionalOnBean, @ConditionalOnSingleCandidate and @ConditionalOnWebApplication #13328

Closed YannCebron closed 6 years ago

YannCebron commented 6 years ago

Proposal:

For known Condition implementations, we "know" that they technically contain a "virtual" @ConditionalOnClass condition.

Sample: org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition#isServletWebApplicationeffectively equals @ConditionalOnClass("org.springframework.web.context.support.GenericWebApplicationContext") performed by corresponding ClassUtils.isPresent() call.

Benefits:

  1. Improved startup time for application
  2. Improved performance in IDEs using such metadata (as IntelliJ IDEA already does)

TBD: How can such knowledge be provided/maintained for any custom Condition implementation wishing to participate in this metadata generation.

philwebb commented 6 years ago

I'm not sure we can do that. The OnWebApplicationCondition#isServletWebApplication method is only called for @ConditionalOnWebApplication(type=SERVLET) so it's not always the case that we can filter those auto-configuration class out early.

Perhaps I've misunderstood the suggestion?

YannCebron commented 6 years ago

True, is it not possible to evaluate annotation attribute values in annotation processor?

philwebb commented 6 years ago

Possibly. I think I'd rather make OnWebApplicationCondition a AutoConfigurationImportFilter and filter out configurations directly there. I don't like the idea of adding too much knowledge to the annotation processor.

snicoll commented 6 years ago

That would also duplicate the knowledge about the target type. But perhaps there is something else that could be made. Like @ConditionalOnBean(Foo.class) on @Configuration translates to @ConditionalOnClass(Foo.class). If Foo.class isn't on the classpath, there is no need to load the class at all.

YannCebron commented 6 years ago

w/r to previous comment, this is the list for SB 2.0.3 (includes all listed starters from start.spring.io)

@ConditionalOnBean w/o @ConditionalOnClass: (38)
  de.codecentric.boot.admin.server.cloud.config.AdminServerDiscoveryAutoConfiguration
  de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration
  de.codecentric.boot.admin.server.config.AdminServerHazelcastAutoConfiguration
  de.codecentric.boot.admin.server.ui.config.AdminServerUiAutoConfiguration
  io.pivotal.spring.cloud.service.config.VaultTokenRenewalAutoConfiguration
  org.apache.camel.model.rest.springboot.RestConfigurationDefinitionAutoConfiguration
  org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration
  org.apache.camel.spring.boot.cloud.CamelCloudServiceCallConfigurationAutoConfiguration
  org.apache.camel.spring.boot.cloud.CamelCloudServiceChooserAutoConfiguration
  org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscoveryAutoConfiguration
  org.apache.camel.spring.boot.cloud.CamelCloudServiceFilterAutoConfiguration
  org.springframework.boot.actuate.autoconfigure.metrics.cache.CacheMetricsAutoConfiguration
  org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration
  org.springframework.boot.actuate.autoconfigure.metrics.web.reactive.WebFluxMetricsAutoConfiguration
  org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration
  org.springframework.cloud.client.hypermedia.CloudHypermediaAutoConfiguration
  org.springframework.cloud.config.server.config.ConfigServerAutoConfiguration
  org.springframework.cloud.consul.discovery.RibbonConsulAutoConfiguration
  org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration
  org.springframework.cloud.netflix.eureka.config.EurekaDiscoveryClientConfigServiceAutoConfiguration
  org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration
  org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
  org.springframework.cloud.sleuth.annotation.SleuthAnnotationAutoConfiguration
  org.springframework.cloud.sleuth.instrument.async.AsyncCustomAutoConfiguration
  org.springframework.cloud.sleuth.instrument.async.AsyncDefaultAutoConfiguration
  org.springframework.cloud.sleuth.instrument.messaging.TraceMessagingAutoConfiguration
  org.springframework.cloud.sleuth.instrument.scheduling.TraceSchedulingAutoConfiguration
  org.springframework.cloud.sleuth.instrument.web.TraceHttpAutoConfiguration
  org.springframework.cloud.sleuth.instrument.web.TraceWebAutoConfiguration
  org.springframework.cloud.sleuth.instrument.web.TraceWebFluxAutoConfiguration
  org.springframework.cloud.sleuth.instrument.web.TraceWebServletAutoConfiguration
  org.springframework.cloud.sleuth.instrument.web.client.TraceWebClientAutoConfiguration
  org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsBinderSupportAutoConfiguration
  org.springframework.cloud.stream.config.ChannelBindingAutoConfiguration
  org.springframework.cloud.stream.reactive.ReactiveSupportAutoConfiguration
  org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration
  org.springframework.cloud.zookeeper.discovery.RibbonZookeeperAutoConfiguration
  org.springframework.cloud.zookeeper.discovery.ZookeeperDiscoveryAutoConfiguration