How to Build Custom @Enable Annotations in Spring Boot
This guide explains the purpose of Spring Boot's @Enable* annotations, how they rely on @Import, and walks through creating a custom @EnablePack annotation with accompanying configuration and usage in a Spring Boot application.
@Enable* annotations in Spring Boot are used to activate specific features, such as @EnableAutoConfiguration for automatic configuration, @EnableAsync for asynchronous methods, and @EnableConfigurationProperties for binding configuration properties to beans.
Most @Enable* annotations share a common implementation detail: they use the @Import annotation to import one or more component or configuration classes.
The @Import annotation indicates one or more component classes—typically @Configuration classes—to be imported into the Spring context. Since Spring 4.2, @Import also supports importing plain classes without @Configuration.
Below is an example of creating a custom @Enable annotation called
EnablePackthat imports a
Packclass and defines an attribute
maxConnectionswith a default value of 1000.
<code>@Retention(RetentionPolicy.RUNTIME)
@Import(Pack.class)
public @interface EnablePack {
int maxConnections() default 1000;
}</code>The
Packclass implements
ImportAwareand
ApplicationContextAwareto gain access to annotation attributes and the application context.
<code>public class Pack implements ImportAware, ApplicationContextAware {
private ApplicationContext ctx;
private int maxConnections;
@Override
public void setImportMetadata(AnnotationMetadata annotationMetadata) {
Map<String, Object> attributesMap = annotationMetadata.getAnnotationAttributes(EnablePack.class.getName());
AnnotationAttributes attrs = AnnotationAttributes.fromMap(attributesMap);
this.maxConnections = attrs.getNumber("maxConnections");
System.out.println(ctx.getBean(ProductService.class));
System.out.println(this.maxConnections);
}
public void store() {
System.out.println(this.maxConnections);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ctx = applicationContext;
}
}
</code>The
ImportAwareinterface is typically used together with @Import to activate custom functionality. Alternatively, one can extend
AdviceModeImportSelectoror implement
ImportSelectordirectly.
Finally, the custom annotation is used in the Spring Boot application's main class:
<code>@SpringBootApplication
@EnableCaching
@EnablePack(maxConnections = 10000)
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
</code>When the application starts, the console displays the output from the
Packclass, confirming that the custom @EnablePack annotation has been processed.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.