spring boot核心原理:@Conditional

发布时间 2023-06-01 17:19:53作者: zno2

资料


https://docs.spring.io/spring-boot/docs/2.2.2.RELEASE/reference/html/howto.html
https://docs.spring.io/spring-boot/docs/1.2.1.RELEASE/reference/html/boot-features-developing-auto-configuration.html

 

官方文档苦口婆心有点可爱

自动配置核心在于“自动”,但也有可能不生效,下面高速你怎么排查问题
Troubleshoot Auto-configuration
The Spring Boot auto-configuration tries its best to “do the right thing”, but sometimes things fail, and it can be hard to tell why.

There is a really useful ConditionEvaluationReport available in any Spring Boot ApplicationContext.
You can see it if you enable DEBUG logging output.
If you use the spring-boot-actuator (see the Actuator chapter),
there is also a conditions endpoint that renders the report in JSON.
Use that endpoint to debug the application and see what features have been added (and which have not been added) by Spring Boot at runtime.

条件评估报告,可以在debug日志看,可以actuator看,另外就是看源码和doc文档,遵循下面的经验法则提高效率

Many more questions can be answered by looking at the source code and the Javadoc.
When reading the code, remember the following rules of thumb:

Look for classes called *AutoConfiguration and read their sources.
Pay special attention to the @Conditional* annotations to find out what features they enable and when.
Add --debug to the command line or a System property -Ddebug to get a log on the console of all the auto-configuration decisions that were made in your app.
In a running application with actuator enabled, look at the conditions endpoint (/actuator/conditions or the JMX equivalent) for the same information.

最快的方式还是学习别人的配置,搜源码小技巧 Ctrl+Shift+T Open Type ,输入 *AutoConfiguration ,看到一大堆比如WebMvcAutoConfiguration

Look for classes that are @ConfigurationProperties (such as ServerProperties) and read from there the available external configuration options.
The @ConfigurationProperties annotation has a name attribute that acts as a prefix to external properties.
Thus, ServerProperties has prefix="server" and its configuration properties are server.port, server.address, and others.
In a running application with actuator enabled, look at the configprops endpoint.

搜索@ConfigurationProperties 等注解被引用的地方

Look for uses of the bind method on the Binder to pull configuration values explicitly out of the Environment in a relaxed manner.
It is often used with a prefix.

org.springframework.boot.context.properties.bind.Binder 什么鬼??

Look for @Value annotations that bind directly to the Environment.

Look for @ConditionalOnExpression annotations that switch features on and off in response to SpEL expressions,
normally evaluated with placeholders resolved from the Environment.


搜索@ConditionalOnExpression 等注解被引用的地方

 

下面告诉你如何自动化,都有哪些方式

 

32. Developing auto-configuration and using conditions
If you work in a company that develops shared libraries,
or if you work on an open-source or commercial library,
you might want to develop your own auto-configuration.
Auto-configuration classes can be bundled in external jars and still be picked-up by Spring Boot.

32.1 Understanding auto-configured beans
Under the hood, auto-configuration is implemented with standard @Configuration classes.
Additional @Conditional annotations are used to constrain when the auto-configuration should apply.
Usually auto-configuration classes use @ConditionalOnClass and @ConditionalOnMissingBean annotations.
This ensures that auto-configuration only applies when relevant classes are found and when you have not declared your own @Configuration.

You can browse the source code of spring-boot-autoconfigure to see the @Configuration classes that we provide (see the META-INF/spring.factories file).

32.2 Locating auto-configuration candidates
Spring Boot checks for the presence of a META-INF/spring.factories file within your published jar.
The file should list your configuration classes under the EnableAutoConfiguration key.

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
You can use the @AutoConfigureAfter or @AutoConfigureBefore annotations if your configuration needs to be applied in a specific order.
For example, if you provide web specific configuration, your class may need to be applied after WebMvcAutoConfiguration.

32.3 Condition annotations
You almost always want to include one or more @Condition annotations on your auto-configuration class.
The @ConditionalOnMissingBean is one common example that is used to allow developers to “override” auto-configuration if they are not happy with your defaults.

Spring Boot includes a number of @Conditional annotations that you can reuse in your own code by annotating @Configuration classes or individual @Bean methods.

32.3.1 Class conditions
The @ConditionalOnClass and @ConditionalOnMissingClass annotations allows configuration to be skipped based on the presence or absence of specific classes.
Due to the fact that annotation meta-data is parsed using ASM you can actually use the value attribute to refer to the real class,
even though that class might not actually appear on the running application classpath.
You can also use the name attribute if you prefer to specify the class name using a String value.

32.3.2 Bean conditions
The @ConditionalOnBean and @ConditionalOnMissingBean annotations allow configurations to be skipped based on the presence or absence of specific beans.
You can use the value attribute to specify beans by type, or name to specify beans by name.
The search attribute allows you to limit the ApplicationContext hierarchy that should be considered when searching for beans.

[Note]
@Conditional annotations are processed when @Configuration classes are parsed.
Auto-configure @Configuration is always parsed last (after any user defined beans),
however, if you are using these annotations on regular @Configuration classes,
care must be taken not to refer to bean definitions that have not yet been created.

32.3.3 Resource conditions
The @ConditionalOnResource annotation allows configuration to be included only when a specific resource is present.
Resources can be specified using the usual Spring conventions, for example, file:/home/user/test.dat.

32.3.4 Web Application Conditions
The @ConditionalOnWebApplication and @ConditionalOnNotWebApplication annotations allow configuration to be skipped depending on whether the application is a web application.
A web application is any application that is using a Spring WebApplicationContext,
defines a session scope or has a StandardServletEnvironment.

32.3.5 SpEL expression conditions
The @ConditionalOnExpression annotation allows configuration to be skipped based on the result of a SpEL expression.

 

原理是什么

 思路还是看源码,怎么快速定位是如何使用呢,借助 @ConditionalOnExpression 

因为SpEL 可以执行类的静态方法,所以思路就简单了,自己建一个类,一个静态方法返回boolean ,打上断点

 

断点后堆栈信息如下图:

 还是在扫描注册component组件阶段,通过postProcessor ,加上反射实现的

 

开发自己的自动化配置

1. 应用场景

 

2. 实现