Feature flags for Spring Boot — annotations, AOP, and safe rollouts
Sign up at flagbit.anethoth.com to get your SDK key. The free tier includes 1,000 evaluations/day.
com.squareup.okhttp3
okhttp
import okhttp3.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.Cacheable;
import java.util.Map;
@Service
public class FlagBitService {
private final OkHttpClient client = new OkHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
@Value("${flagbit.sdk-key}")
private String sdkKey;
@Cacheable(value = "flags", key = "#flagKey + #context.hashCode()")
public boolean isEnabled(String flagKey, Map<String, String> context) {
try {
String body = mapper.writeValueAsString(Map.of(
"flag_key", flagKey,
"context", context != null ? context : Map.of()
));
Request request = new Request.Builder()
.url("https://flagbit.anethoth.com/api/v1/evaluate")
.addHeader("X-SDK-Key", sdkKey)
.addHeader("Content-Type", "application/json")
.post(RequestBody.create(body, MediaType.parse("application/json")))
.build();
Response resp = client.newCall(request).execute();
var result = mapper.readTree(resp.body().string());
return result.get("value").asBoolean();
} catch (Exception e) {
return false;
}
}
}
// Custom annotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FeatureFlag {
String value();
}
// AOP aspect
@Aspect
@Component
public class FeatureFlagAspect {
@Autowired private FlagBitService flagBit;
@Around("@annotation(flag)")
public Object checkFlag(ProceedingJoinPoint jp, FeatureFlag flag) throws Throwable {
if (flagBit.isEnabled(flag.value(), Map.of())) {
return jp.proceed();
}
throw new ResponseStatusException(HttpStatus.NOT_FOUND);
}
}
// Controller usage
@RestController
public class DashboardController {
@FeatureFlag("new-analytics")
@GetMapping("/api/analytics/v2")
public ResponseEntity<?> newAnalytics() {
return ResponseEntity.ok(analyticsService.getV2Data());
}
}
Feature flags are more granular than Spring profiles — toggle individual features without restarting the JVM.
Roll out new endpoints to a percentage of users before full deployment across all instances.
Dual-read from old and new schemas during migration — flag controls which path executes.
Run server-side experiments with consistent user bucketing via percentage rollouts.
Define flags in your FlagBit dashboard with targeting rules and rollout percentages.
Call the evaluate endpoint from your Spring Boot app with user context for targeted rollouts.
Enable, disable, or adjust rollouts in real-time. No redeployment needed.
FlagBit is hosted — no JPA entities, no Spring Security integration needed, no self-hosting. Simple HTTP API.
Use Spring's @Cacheable with a TTL-based cache (Caffeine or Redis). The example above shows this pattern.
Yes — the Java SDK works in Kotlin. You can also use Kotlin coroutines with the suspend version of the HTTP call.
Use WebClient instead of OkHttp and return Mono
Free tier includes 1 project, 10 flags, and 1,000 evaluations/day. No credit card required.
Get Your Free API Key