Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Conditional annotation works in Spring Boot?

I understand that Spring Boot has lots of @Conditional annotations like, @ConditionalOnBean, @ConditionalOnClass, @ConditionalOnProperty, ConditionalOnWebApplication. But I do not know how this work?

For Example:

@Configuration    
@ConditionalOnClass(MyBean.class)
public class MyConfiguration{
    // omitted       
}

What I understood is, MyConfiguration will be loaded only if MyBean is available in my classpath. But how would it compile and run if MyBean class is not in my class path as the compiler reaches to @ConditionalOnClass(MyBean.class) line, wont it throw compiler error? As soon as I add such code in my eclipse, I am getting compile time error. Sorry if this is too basic question but I do not know what I am missing to understand.

like image 590
sabtharishi Avatar asked Sep 14 '17 16:09

sabtharishi


3 Answers

Spring Boot is being compiled with lots of optional dependencies; so when Spring Boot is compiled, the MyBean.class is on the classpath.

Now your application may not have that MyBean.class in its classpath, but it doesn't fail at runtime. This is because the infrastructure that processes @ConditionalOnClass annotations will actually read the bytecode of the configuration and will only load them if that MyBean.class is present. See @ConditionalOnClass javadoc.

Now auto-configuration is a broad subject, and you can learn more about this in this talk.

like image 85
Brian Clozel Avatar answered Oct 19 '22 07:10

Brian Clozel


As the Spring Boot Documentation says:

The @ConditionalOnClass and @ConditionalOnMissingClass annotations allows configuration to be included based on the presence or absence of specific classes. Due to the fact that annotation metadata 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.

So they use the bytecode manipulation library ASM to be able to parse the class names during runtime, even if the classes are not anymore on the classpath. Since Spring is open source, you can even just go look at the annotation reading code.

like image 3
jhyot Avatar answered Oct 19 '22 06:10

jhyot


You would typically use Optional dependencies:

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <optional>true</optional>
</dependency>
like image 1
Kyle Anderson Avatar answered Oct 19 '22 06:10

Kyle Anderson