Backend Development 4 min read

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.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
How to Build Custom @Enable Annotations in Spring Boot

@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

EnablePack

that imports a

Pack

class and defines an attribute

maxConnections

with a default value of 1000.

<code>@Retention(RetentionPolicy.RUNTIME)
@Import(Pack.class)
public @interface EnablePack {
    int maxConnections() default 1000;
}</code>

The

Pack

class implements

ImportAware

and

ApplicationContextAware

to 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

ImportAware

interface is typically used together with @Import to activate custom functionality. Alternatively, one can extend

AdviceModeImportSelector

or implement

ImportSelector

directly.

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

Pack

class, confirming that the custom @EnablePack annotation has been processed.

Javabackend developmentSpring BootCustom Annotation@Import@Enable
Spring Full-Stack Practical Cases
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.