Please help to explain a strange combination of Lombok's #AllArgsConstructor and spring's #RestController - spring-mvc

I'm working on a spring project from our customer.
Below is the code for controller
#Log4j2
#RestController
#AllArgsConstructor
#RequestMapping(path = "/api/theapi")
#Api(value = "Description for the API")
public class TheAPIController {
private final ModelMapper modelMapper;
private final ObjectMapper objectMapper;
private final TheDemoService demoService;
...other code for controller
}
Below is the code for Service:
#Service
public class TheDemoService{ ... }
I was so surprise about 2 things:
Question 1: Why we need to use #AllArgsConstructor from project Lombok?
As per my understanding, Spring provide #RestController that Spring runtime container will initialize an Instance for our Controller. So that, having a constructor for our Controller seems like an invalid approach for using Spring Inversion of Control, is this correct?
Question 2. Because of using #AllArgsConstructor, somehow, the instance for demoService is to be injected
But again, I surprise because the code of Controller does not have #Autowired in combine with demoService.
In the actual code, there is no #Autowired for "private final TheDemoService demoService".
Hence, I could think of a possibility there, is that because of Lombok's #AllArgsConstructor would inject an instance of our TheDemoService via a constructor of
TheAPIController, I could not reason anything about this logic.

It's Invalid approach, no need for defining constructor for RestController
It's implicitly auto wiring the service
if a class, which is configured as a Spring bean, has only one constructor, the Autowired annotation can be omitted and Spring will use that constructor and inject all necessary dependencies.
To sum up #AllArgsConstructor can/should be removed

Related

what is the relation between GenricServlet and ServletConfig?

A GenericServlet is a type of ServletConfig, also GenericServlet has a ServletConfig. What is logic in this? How should I understand this?
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final long serialVersionUID = 1L;
private transient ServletConfig config;
..
}
The ServletConfig is an interface and is implemented by services in order to pass configuration information to a servlet when it is first loaded.
GenericServlet implements ServletConfig. It's not a subclass of ServletConfig. Understand the difference between a subclass and interface.
GenericServlet class implements Servlet, ServletConfig and Serializable interfaces. It provides the implementation of all the methods of these interfaces except the service method.
GenericServlet class can handle any type of request so it is protocol-independent.
You may create a generic servlet by inheriting the GenericServlet class and providing the implementation of the service method.
Visit here for more

Avoid proliferation of #MockBeans in Spring Boot #WebMvcTest test

I have a simple controller e.g.
#Controller
public class FooController
{
#Autowired
private BarService barService;
#RequestMapping(value = "/foo", method = RequestMethod.GET)
public String displayFoo()
{
return "foo";
}
}
When I want to do a #WebMvcTest, I have to create a great number of #MockBeans to prevent a NoSuchBeanDefinitionException.
#RunWith(SpringRunner.class)
#WebMvcTest
#Import(WebSecurityConfig.class)
public class FooControllerTest
{
#MockBean ...
#MockBean ...
#MockBean ...
...
...
}
Does this mean that BarService is somehow creating a chain of dependencies? (it has some dependencies but some #MockBeans appear completely unrelated).
The problem is, is that each #WebMvcTest I add for different controllers also requires the same #MockBeans.
Should I be using an annotation like #TestConfiguration to specify all the #MockBeans for the DRY principal?
I looked at this again, and found you can pass the controller name to #WebMvcTest e.g. #WebMvcTest(FooController.class).
Specifies the controllers to test. May be left blank if all {#code
#Controller} beans should be added to the application context.
As Hal8k said, if you don't specify a controller like #WebMvcTest(YourController.class), it will try to load all #Controller components. And #Import(WebSecurityConfig.class) also try to inject components in WebSecurityConfig.class.
Refer : https://spring.io/blog/2016/08/30/custom-test-slice-with-spring-boot-1-4
This could happen when the bean scanning configuration is faulty or excessive.
In my case, I was still getting the error despite having specified the controller to test in #WebMvcTest(FooController.class).
I eventually realised it was due to the #ComponentScan of my application being needlessly cluttered up. My Application.java was something like this:
#SpringBootApplication
#ComponentScan({"fr.nevechris.projectname","fr.nevechris.projectname.otherpackage"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I removed the #ComponentScan entirely and the issue was solved.
If your #ComponentScan is good or not specified, try searching for other places in your project where configuration is done (eg #Configuration tag).

How to inject DAO bean in tapestry (with Spring JDBC)

I am using Spring-JDBC with Tapestry and not able to inject DAO bean which I have defined in Spring.xml. Normally we use applicationContext.getBean, but in tapestry I am not able to find such option. Please guide me how I can inject DAO bean to use it in my code. Below is kind of code I am having:
Class ABC{
with private members, getters,setters and constructors
}
Class abcDAO{
private JdbcTemplate template
//getter and setter for jdbc template
//a method which will extract data using Rowmapper
public Set<ABC> getAll(){
//override mapRow method
}
}
I want to use getAll method in a class which will process extracted data. Please help me where should I inject abcDAO bean with below line:
#Inject private abcDAO abcDao;
Thanks in advance!!!

Best way to pass reference of injected dependency in spring controller

I have a Spring portlet controller class. In this class, there is a dependency like this:
#Autowired
protected ServiceClass someService;
#Autowired
protected ApplicationContext context;
From the controller, there is a utility class being called like this:
UtilityClass.loadStaticData((WebApplicationContext)context);
Inside UtilityClass, I have:
public static synchronized boolean loadStaticData(WebApplicationContext context){
ServiceClass someService = (ServiceClass) context.getBean("someService");
...
}
My question is: Is there any advantage to getting the handle of the someService in such a complicated way? We could have just passed the reference 'someService' from Controller class #1 to the UtilityClass. The author is no longer available so I am asking here.
This is basically what dependency injection tries to avoid: getting a dependency from the container instead of having the dependency injected by the container.
This utility class should be a Spring bean, where the service would be injected. And you could then inject this utility bean inside the controller.

Different between Autowired Services and Objects Spring MVC

I was wondering what is the difference between creating a new class and injecting it with the #Autowired annotation and creating a class and take the object of this class and using its methods. Is there any techical reason(i.e. faster access etc)?
Service case:
#Service
public class AuthorService implements AuthorServiceInterface {
//some methods
}
Simple Class case:
public class AuthorService implements AuthorServiceInterface {
//some methods
}
If i want to call the first one in another class i have to write:
public Class myclass{
#Autowired
AuthorService authorservice;
}
In the second case i have to write:
public Class myclass{
AuthorService authorservice = new AuthorService():
}
Whats the difference between these two cases?
The first snippet uses dependency injection, and the second doesn't. Dependency injection allows
decoupling MyClass from the concrete implementation of AuthorService which would allow switching implementations depending on the environment for example
using a singleton (or session-scoped or request-scope) AuthorService rather than reinstantiating one each time
injecting a mock AuthorService implementation when unit-testing MayClass
injecting a proxy around the concrete AuthorService instance, which could
verify authorizations
start a transaction before each method call and commit/rollback it after the method call
log the method calls
measure the time taken by methods and compute statistics
invoke an AuthorService on another machine, using RMI or HttpInvoker
...
Note that you should autowire AuthorServiceInterface, and not AuthorService, in MyClass.

Resources