Simple Feature Toggles with Spring Boot

Mario Scalas
4 min readJun 25, 2020

In this article I will write about feature flags to help improving testability of Spring Boot Apps. While this is not a comprehensive overview about the subject, I will share my experience and then provide you some references if you are too busy (lazy) to google them by yourself :)

Note for the reader: this article is about Spring Boot and it assumes you are moderately familiar with the subject.

Motivation and context

When you design your Spring Boot App by vertical features you probably have in mind specific architectural constraints (e.g., Clean Code architecture) and you want to test each of your features isolated by the others.

Another requirements, with Spring Boot Tests, may involve performance reasons: you want the smallest amount of Spring components to be loaded / initialized and made available because otherwise your tests become slow.

You want your test to be as fast as possible otherwise people may be tempted to skip running tests during their normal workflow because “they slow me down”.

And no, using @MockBean does no help because the Spring Context gets trashed (“dirtied” in Spring terms) and you pay a heavy price in execution time because the JUnit Spring extension will have to recreate it each time a method is run (of course, you may change it to run it for class and spare some time).

Modularization in Spring Boot

Slicing a Spring Boot App may happen in several ways. For example, you may define different Spring profiles (one for each feature) and then activate them at runtime.

Another solution, which has interesting advantages in the development workflow, is using feature toggles (AKA ‘feature flags’) to group Spring components (like @Controllers, @Services, @Components and so on)

And of course, you can work with both profiles and feature toggles in order to slice your system in logical and coupled parts that can be assembled together while also be tested in isolation.

My usecase

My use case is pretty simple: I want to activate / deactivate Spring components as easy as possible without too much configuration. The idea is to define boolean properties in your application.yaml and then use them at runtime in order to turn components on and off. Something like:

ftd:
feature:
hello: true

About the implementation

For my implementation, I initially started looking at the customary @ConditionalOnProperty:

@ConditionalOnProperty( value = "ftd.feature.hello", matchIfMissing = true, havingValue = "true" )
public class HelloServiceImpl implements HelloService {
// ...
}

I didn’t like the resulting code because

  • it was verbose, requiring me to duplicate the full property prefix every time (“ftd.feature.”, in this case);
  • if I want to change my logic from “enabled by default” to “disabled by default” and back, I have to go around every parts of my application and change the annotation values.

I started by creating meta-annotations but I failed miserably and I went for other ways, like implementing my own conditional logic, which Spring allows to easily plug into your application.

In practices, you:

  1. define your own annotation (e.g., FeatureToggle);
  2. implement the conditional logic (in my case going to check the properties and applying by activation rules).

Yep, that easy!

FeatureToggle implementation

FeatureTogglingCondition implements the activation logic: it accesses the Spring environments and it looks up for the required property. As I said: features are always enabled unless explicity disabled. Returning the right boolean values, makes the Spring runtime to pubblish or not the annotated Spring component.

Next step is to go around annotating Spring components, for example:

Feature toggles and Spring components

My business rules are really plain: features are enabled by default unless explicity disabled (your requirements may be different). So when my application starts up, all features are available (unless I disable them by setting the related flags to false). In my test, instead, I use the opposite logic: all features are disabled and in each test I explicitly enable the features I need:

Activating features during tests

In this way I only enable what is needed during my Spring Boot Tests and speed up the execution time (of course, you need something more complex than a hello world app to feel the change!).

In order to do that I find the well known @TestPropertySource useful because I can ovverride the properties on the fly: since my features are all disabled by configuration during tests, I effectively activate only the feature I need for tests.

You can look at the code and try it by yourself on a demo project on GitHub.

Conclusions and references

The code I presented here is simple (too simple for enterprise requirements) but it has given me the chance to know more about feature flagging in Spring Boot and I thought it was worth sharing.

You may want to explore the topic further by yourself, for example you may want an enterprise-grade solution which covers a lot more use cases like FF4J — Feature Flipping for Java . Other articles I found useful:

I hope you found this article to be interesting: if you have any comments or questions, please feel free to share them.

Happy coding and have fun!

--

--

Mario Scalas

I’m a software engineer / solution architect / team coach and I’m passionate about software development practices, technologies and software processes.