问题
I have a working Spring Boot application which includes a class like this:
@RestController
@Validated
@RequestMapping("/HelloWorld")
public class HelloWorldController
{
private static int foo = getFoo ();
private static int getFoo ()
{
System.out.println ("HelloWorldController getFoo");
return 0;
}
public HelloWorldController ()
{
System.out.println ("HelloWorldController Constructor");
}
@GetMapping("/get")
public HelloWorld root ()
{
return new HelloWorld ("Hello, world!");
}
}
The /get
request is served as expected. When the application starts I can see both println
outputs.
In a separate project I have a similar class:
@RestController
@Validated
@RequestMapping("/api")
public class ModularAPIDemoController
{
private static int foo = getFoo ();
private static int getFoo ()
{
System.out.println ("ModularAPIDemoController getFoo");
return 0;
}
public ModularAPIDemoController ()
{
System.out.println ("ModularAPIDemoController Constructor");
}
@GetMapping("/get")
public Message root ()
{
return new Message ();
}
}
The second class is built in a mylib
library using maven and the application pom.xml
includes it with
<dependency>...<artifactId>mylib</artifactId>...</dependency>
When the application.jar
builds I can see mylib.jar
within BOOT-INF/lib
however when the service starts I see the println
from HelloWorldController
but not from ModularAPIDemoController
, and the /api/get
request does not work.
I want a java library which includes @RequestMapping
annotated classes as well as other Spring annotations such as @Configuration
and @EnableWebSecurity
and various other things.
The libraries and applications are being built with Maven. How can I set it up so that Spring loads the annotated classes which are within library dependencies?
回答1:
Add explicitly the packages which are you scanning for this components. Use the annotation @ComponentScan
together with the annotation @SpringBootApplication
so you overwrite the default behavior and add the two package roots like this:
@ComponentScan(basePackages = {"package1", "package2"})
回答2:
In your project you have a class which is annotated with @SpringBootApplication
. By default Spring Boot scans all sub packages (including the package where this class is located) for components (e.g. annotated classes). If your library does not live within some of the sub packages, then you can make it eligible for component scanning by adding the root package of your library in @SpringBootApplication
, as documented i.e.
@SpringBootApplication(scanBasePackages = {"path.to.your.project.root", "path.to.your.library.root"})
This way Spring Boot also scans your library for components. As a consequence of the way how this @ComponenScan
works, you should put your @SpringBootApplication
-annotated class in a well defined root package of your project (e.g. org.foo.bar
). Do not put the @SpringBootApplication
-annotated class into default package since Spring Boot might scan for components from other libraries that you do not want to be scanned.
However, I am not sure if I were putting these classes in a library...
来源:https://stackoverflow.com/questions/61454078/how-can-i-make-springboot-annotated-classes-load-properly-when-they-are-in-a-lib