Spring - separate directory for controllers - java

I'm a newbie in Spring and have one question about inserting all controllers in another directory than an executable spring boot file.
This tutorial
I have to have GreetingController.java and Application.java in one directory because if not, then I can't run mvn spring:boot-run
Is there a way to have Application.java in /java directory and all controllers in /java/controllers? Can I create some config file to inform Application.java where all the files are?
Thank you

I am little bit confused. But first point - It is good to have all controllers in separate directory, it is best practise, but better is using /rest directory.
Second point - You have to define application context and enable few things (for example via annotation). Try to look here http://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.html, here you can see annotations and basic structure.
For you, set this annotations to your Application.java:
#Configuration
#EnableAutoConfiguration
#ComponentScan
More information and where to write it you can find in link what I posted.
If you configure application context and you set EnableAutoconfiguration and ComponentScan, Spring will look up for all annotated components and your controllers (if you annotated you controller class by #Controller annotation.

Related

Component Scan using application.properties in spring boot app

I made a java library that has component and configuration classes.
When I use the library in other spring boot services, the beans are not registered because the component and configuration classes are not in the classpath.
I know we can use #ComponentScan but I don't want to change the service's code.
Is there a way of adding the classes to the classpath using application.properties?
Or is there anything I can do in the library so that the beans get registered?
If you are using Spring Boot, you can take advantage of Spring Autoconfiguration.
For that, you need to place a file spring.factories in META-INF/spring.factoriesin your library's .jar file. If you are using Gradle or Maven as a build tool and the standard folder structure, the file path is src/main/resources/META-INF/spring.factories.
Here's an example from a library I wrote:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.requirementsascode.spring.behavior.web.BehaviorConfiguration,\
org.requirementsascode.spring.behavior.web.SerializationConfiguration,\
org.requirementsascode.spring.behavior.web.BehaviorController
As you can see, after the first, Spring specific line, you list all of your configuration classes.
You can learn more about autoconfiguration here, for example.
You can do this using the autowireBean() method of AutowireCapableBeanFactory.
Read more here: AutowireCapableBeanFactory

#ComponentScan for every package in project

Is it possible to let #ComponentScan work on whole Spring Boot project? Now when I create a new package, I need to add it into #ComponenScan annotation otherwise beans won't be found. If it's possible to allow to search everywhere in project can it cause performance problems or any other issues?
Example:
first component StorageRoom\backend\src\main\java\com.storeage (here is main class with #ComponentScan annotation)
second component StorageRoom\backend\src\main\java\security
third component StorageRoom\backend\src\main\java\component3
#ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.
So for your problem, I would recommend that you should have your main class at the root of the application and then annotate it with #ComponentScan there.
Something like here -
StorageRoom\backend\src\main\java\SpringBootApplicationMain.java
Find more here: https://www.baeldung.com/spring-component-scanning

Internal Implementation of IOC and DI in Spring Boot

Whenever spring boot application runs it sees the #SpringBootApplication annotation and runs the #ComponentScan which scans the classes with the annotations such as #Component etc and makes the object in the container.I have a little bit of idea that it might be using reflections internally to create the objects but I am not able to connect all the dots .I want to know what exact information does #AutoConfiguration gives to the container that it is able to get all the information of all the component annotated clases of any component ?
P.s. I have edited the wrong question
First of all #AutoConfiguration is responsible for setting up the default configurations for a Spring boot application depending on the dependencies we have added in the pom.xml.
The thing you are looking for is #ComponentScan which is what performs the component class scanning within the default package and all of its sub packages. It does this by going through each class in the package and looking for the #Component,#Service or #Repository annotations. If any of them is present then the container adds this as a bean.
#SpringBootApplication internally has the #ComponentScan annotation added to it along with two others.

How to find entry point of a Spring Boot application?

What is the entry point of a spring boot application?
While going through a Spring Boot application code, all that it says is there is a code
public static void main having - SpringApplication.run(Application.class, args)
Example - SpringBoot2RestServiceApplication.java .
But how to get to know what is the entry point, just by going through the code. Earlier, if we go through applicationContext.xml - example - applicationContext.xml, we could understand the flow.
Is there any way, or maybe a standard to follow to make this understanding self-explanatory?
My question was more of understanding the flow of the application than finding the main class. One option could be separating configurations(#Configuration) to a separate class having multiple #Bean annotations, this would help in finding all bean wirings at one place. Is there a standard that large projects use to make code flow understandable?
The easiest thing to do would probably be to search for #SpringBootApplication in your code.
But, a guaranteed way to get this information would be to build the Spring Boot JAR. From there, you can open the resulting JAR and find the main class defined in the manifest, under META-INF/MANIFEST.MF. You'll see it under the Start-Class attribute:
Start-Class: com.example.foo.Application
I think the OP is studying an existing Spring Boot application, and is asking how to locate any runner, such as Application Runners, Command Line Runners, MVC controllers, Rest controllers, etc.
I don't know if there is an easy way to locate those, unless they are grouped together in the original design.
It's a difficult problem to do programmatically, because threads can be launched outside of Spring, for example in a constructor or a #PostConstruct.
It would be nice though if there were IDE support to easily locate anything that gets launched by Spring Boot
search #SpringBootApplication annotation in your project, the class with #SpringBootApplication annotation will automatically do the component-scan for the sub packages.
if no #SpringBootApplication annotation found, search the class extending "SpringBootServletInitializer" which is also a starting point for the spring boot application
The Entry of any spring boot application has an annotation of #SpringBootApplication

How is Spring's basePackages scan retrieving my classes from a different Maven module?

I'm getting confused now with packages. It's broken down like this: Simple Maven multi module project. One parent POM, two sibling module children (one is a service module, one is a web module to be ran in Tomcat).
Below is my Spring Annotation Config for Dispatcher Servlet. Here is where I am confused. At first I didn't think basePackages was going to be able to scan for packages in a totally separate module (which is the service module). However, it somehow worked, exactly as written below. 'Entities' and 'Services' are the two packages from the Service module, while 'Controllers' comes from THIS web module. Let it be known that I have in fact added the Service module as a dependency into my web module. Nothing crazy going on there. Simple dependency so I can have access to my Service classes.
#EnableWebMvc
#Configuration
#ComponentScan(basePackages={"entities", "services", "controllers"})
public class DispatcherConfig {
}
What I don't understand is how the packaging is working. It's all spaghetti'd in my mind now. When Spring gets to the line #ComponentScan and sees "entities", and "services", what is the structure it is looking on to get these classes?
My package structure is very simple. In the Service module I simply have src/main/java/entities and src/main/java/services
Something is happening behind the scenes here that I don't understand. How come Spring is smart enough to know this? I didn't even have to list the full package, i.e. myproject/src/main/java/entities or something like that?
Thanks
suppose #ComponentScan uses string array, like this:
#ComponentScan({"com.package.first","com.my.package.second"})
When you provide multiple package names in only one string, Spring interprets this as one package name.
This post might be helpful.

Categories

Resources