In my Maven, Spring Boot 2 project I have Maven module called api1
. I have declared a number of @RestController
s there.
In order to extend the logic of the api1
module, I have implemented another Maven module called api2
and placed api1
there as Maven dependency.
Right now all of the @RestController
s from api1
project are initialized in the api2
because all of them are present on the api2
classpath.
How to disable a certain @RestController
in api2
project?
I think the crucial fact here to understand is that Spring works at runtime only, while maven matters in build time.
So maven sees that api2 depends on api1 so it understands that both modules have to be included in the artifact (in the case of spring boot its a big jar with all modules inside).
Now, when spring starts - it "takes for granted" that all modules are accessible, and depending on spring configurations it just defines beans to be loaded and processed, all rest controllers are among these beans of course.
So I assume, you don't mind having two modules in the artifact (and in classpath).
In this case, you shouldn't touch the maven part at all, but when the spring boot application starts it has to be "instructed" somehow that some rest controllers have to be excluded. The point is that it should be done not in terms of modules ("hey, spring, this controller belongs to module api2, so it has to be excluded"), but in terms of business "jargon". For example, api1 contains all "admin" functionality and api2 contains all "applicative" stuff. So, if you work with Java configurations, for example, you can do the following:
Inside module api1:
@Configuration
@ConditionalOnProperty(name = "admin.enabled", havingValue=true)
public class AdminControllersConfiguration {
@Bean
public AdminControllerFromModuleApi1 adminController() {
return new AdminControllerFromModuleApi1();
}
}
}
In module api2 you just define your rest controllers in a similar way but without "@ConditionalOnProperty" annotation.
The thing with this annotation is that it allows to "switch off" beans or entire configurations like in my example.
So, when you start api2, you just define in "application.properties" or something the following:
admin.enabled=false
And your controllers won't be "deployed" by spring although physically the files are certainly in the classpath.
Of course, since spring allows different types of configurations, this method might not be applicable to your project, but the idea is still the same.
You may try using Condition interface from Spring which provide support for conditional enable/disable of the beans based on certain condition/expression.
something like below:
@RestController
@ConditionalOnExpression("${api1.controller.enabled:false}")
@RequestMapping(value = "/", produces = "application/json;charset=UTF-8")
public class Api1Controller {
@RequestMapping(value = "/greeting")
public ResponseEntity<String> greeting() {
return new ResponseEntity<>("Hello world", HttpStatus.OK);
}
}
you have to set the Conditional expression by some way (env. variable / property key). check this for some reference. Condition docs can guide you on more details.