Autowire in spring understanding [duplicate] - spring

This question already has answers here:
Understanding Spring #Autowired usage
(3 answers)
Closed 3 years ago.
When we use #Autowire annotation in spring to crete the object is it mandatory to specify the bean in configuration class ? And how does #Autowired work in springboot?

It's not mandatory in many cases, for instance when injecting objects annotated as #Entity, #Repository, #Controller, #Service or #Component (superclass of all the others) declared
within the main package where the #SpringBootApplication is placed.
You can always place components outside the main package if you declare a component scan in additional packages, using #ComponentScan({"package_1",..."package_n"}) in your #SpringBootApplication class. Remember to include the main package in the list.

Related

Use Spring application properties without starting server [duplicate]

This question already has an answer here:
Spring-boot application-test.properties
(1 answer)
Closed 2 years ago.
We are using Spring Boot 2.3.4
We have some Unit tests where we would only need the application.properties to be loaded (with all it's profile management aso.).
Is it possible to do that without starting the complete Spring Boot server?
EDIT:
I tried the #SpringBootTest annotation, but it always started the whole server, because I referenced the #SpringBootApplication class (or it was referenced automatically).
Actually you don't need all the other annotation, like #ConfigurationProperties
All you need is #SpringBootApplication(classes = AClass.class), where AClass is any class that doesn't have a main method, like your test class for example.
Annotate your test class with #SpringBootTest to load the context.

How SpringBoot dependency injection works with different type of annotations

I recently started exploring Spring Boot. I see that there are 2 ways to define Beans in Spring Boot.
Define #Bean in the class annotated with #SprinBootApplication
Define #Bean in a class annotated with #Configuration
I am also confused about stereo-type annotation #Repository #Service #Controller etc.
Can someone please explain how dependency-injection works with these annotations?
Yes it is possible.
Either you use #Bean in any of your #Configuration or #SpringBootApplication class or mark the bean classes explicitly with annotations like #Service, #Component #Repository etc.
#Service or #Component
When you mark a class with #Service or #Compoenent and if spring's annotation scanning scope allows it to reach to the package, spring will register the instances of those classes as spring beans.
You can provide the packages to be included/excluded during scan with #ComponentScan
#Bean
#Beans are marked on factory methods which can create an instance of a particular class.
#Bean
public Account getAccount(){
return new DailyAccount();
}
Now in you application you can simply #Autowire Account and spring will internally call its factory method getAccount, which in turn returns an instance of DailyAccount.
There is a simple difference of using #Bean vs #Service or #Compoenent.
The first one makes your beans loosely coupled to each other.
In the #Bean, you have flexibility to change the account implementation without even changing any of the account classes.
Consider if your classes instantiation is a multi-step operation like read properties values etc then you can easily do it in your #Bean method.
#Bean also helps if you don't have source code access to the class you are trying to instantiate.
Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added.
You need to opt-in to auto-configuration by adding the #EnableAutoConfiguration or #SpringBootApplication annotations to one of your #Configuration classes.
You are free to use any of the standard Spring Framework techniques to define your beans and their injected dependencies. For simplicity, we often find that using #ComponentScan (to find your beans) and using #Autowired (to do constructor injection) works well.
One way is to define #Bean in the class annotated with
#SprinBootApplication
If you see #SprinBootApplication it is combination of many annotation, and one of them is #Configuration. So when you define #Bean in the Main class, it means it's inside #Configuration class.
According to Configuration docs :
Indicates that a class declares one or more #Bean methods and may be
processed by the Spring container to generate bean definitions and
service requests for those beans at runtime.
class annotated with #Configuration
When you define #Bean is a class annotated with #Configuration class, it means it is the part of spring configuration all the Beans define in it all available for Dependency-Injection.
I have also seen some code where neither of the 2 above approaches
have been used and yet dependency injection works fine. I have tried
to research a lot on this but could not find any concrete answer to
this. Is this possible?
I am assuming you are talking about Sterio-type annotation. Every sterio type annotation has #Component, according to docs :
Indicates that an annotated class is a "component". Such classes are
considered as candidates for auto-detection when using
annotation-based configuration and classpath scanning.

why do we need componentScan in spring

This question might be trivial but still i'm unable to find a good reason or best practice towards #ComponentScan in Spring
DI works just by self annotating the class then why do we need #ComponentScan
What is the best practice towards this?
#ComponentScan tells Spring in which packages you have annotated classes which should be managed by Spring.
Spring needs to know which packages contain spring beans, otherwise you would have to register each bean individually in(xml file). This is the use of #ComponentScan.
Take a simple example, you have a class and annotated with #Controller in a package package com.abc.xyz; , you have to tell the spring to scan this package for Controller class, if spring didn't scan this package, then spring will not identifies it as a controller class.
Suppose if your dealing with configuration file,
<context:component-scan base-package="com.abc.xyz">
like this,
When spring loads the xml file, this tag will search the all the classes present in the package com.abc.xyz, so any of the class containing #controller, #Repository #Service etc.., if it found then spring will register these annotated class in the bean factory.
Suppose if your using spring boot application,
Then your spring-boot application is annotated with The#SpringBootApplication.
#SpringBootApplication annotation is equivalent to using #Configuration, #EnableAutoConfiguration and #ComponentScan with their default attributes.
One more point if you didn;t specify the base package name in #ComponentScan,
it will scan from the package, where the #Springbootapplication present

What is a spring service annotation? [duplicate]

This question already has answers here:
What's the difference between #Component, #Repository & #Service annotations in Spring?
(31 answers)
Closed 5 years ago.
I understand that #Service is used to mark a class as a business logic class. Why is it useful for spring? I can already use #Component to mark a class as a bean. I understand that #Service is more specific than #Component, but how?
Consider #Component annotation as a Swiss Knife. It can act as cutting knife, as an opener, as a scissor, etc.
Similarly, your Component can act as a Repository, as Business Logic class or as a controller.
Now, #Service is a just one of the versions of #Component, say a knife.
Spring process #Service similar to #Component, since #Service interface itself is annotated with #Component.
From Spring docs.:
#Target(value=TYPE)
#Retention(value=RUNTIME)
#Documented
#Component
public #interface Service
Indicates that an annotated class is a "Service" (e.g. a business
service facade).
Why to differentiate both of them?
To apply the basic rule of programming: Your code should be easily readable.
Yes, you can use #Component annotation everywhere and it will work fine but for the better understanding of the code, it is preferred to use the respective special types of annotations like #Service in our case.
The other benefit is ease of debugging. Once you know the error, you need not hope from one component class to another, checking it time whether that class is service, repository or controller.
#Service, #Controller, #Repository = {#Component + some more special functionality}
Click the below link for more details
What's the difference between #Component, #Repository & #Service annotations in Spring?
The #Component annotation marks a java class as a bean so the
component-scanning mechanism of spring can pick it up and pull it into
the application context. The #Service annotation is also a
specialization of the component annotation. It doesn’t currently
provide any additional behavior over the #Component annotation, but
it’s a good idea to use #Service over #Component in service-layer
classes because it specifies intent better. Additionally, tool support
and additional behavior might rely on it in the future.
The #Service annotation is a specialization of the component annotation. It doesn’t currently provide any additional behavior over the #Component annotation, but it’s a good idea to use #Service over #Component in service-layer classes because it specifies intent better. Additionally, tool support and additional behavior might rely on it in the future.

Possible to autowire imported utility classes in Spring?

I want to use data mappers, logger, transfromers, etc. in my Spring web projects. Is it possible to autowire an imported (jar) utility dependency, without wrapping it in some #Component or #Service class? Do we even want to do it that way, or should we just use a static reference?
If your utils, are based on not static methods, then this is simple:
If you use java based configuration, then just declare that util in an #Bean annotated method.
#Configuration
public class YourConfig {
#Bean
public YourUtil util(){
return new YourUtil ();
}
}
in xml it could been as simple as:
<bean id="util" class="org.example.YourUtil" />
The following is true, but it is not what was asked for:
There are at least two other ways to inject beans in instances that are not created (managed) by Spring:
(1) add #Configurable annotation to this class - this requires real AspectJ (compile-time or load-time -weaving)
#see Spring Reference Chapter 7.8.1 Using AspectJ to dependency inject domain objects with Spring
#see this answer of mine https://stackoverflow.com/a/7007572/280244 for a quick "guide" to enable the #Configurable support
(2) invoke SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
#see this question and its (two highes voted answers) for some ideas how to use
You can only #Autowire a bean managed by Spring. So you have to declare your instance through some configuration : a bean in an xml file, or a #Bean method in a java configuration.
#Component are just automatically discovered and registered in the spring context.

Resources