Thursday, April 20, 2023

Spring Boot @Autowired Example - How Autowiring of Beans works in Spring?

Hello guys, if you are wondering how to use @Autowired annotation in Spring Boot and how auto-wiring works in the Spring framework and how the Spring framework magically finds dependency and relevant beans to inject into your program then you have come to the right place. In the past, I have shared how Spring MVC works and in this article, I am going to explain how auto-wiring works in spring and how you can use @Autowired annotation for auto-wiring dependencies in your code. In Spring, you need to know the most important things before starting your coding. From spring 2.5 onwards, the annotations-driven dependency injection was introduced and it is used to inject collaborating beans into the beans. So in this tutorial, we are going to explain how does auto wiring work in spring.

How to enable Auto-wiring  in Spring? @Autowired Example

Spring container can auto-wire relationships between cooperating beans by defining all bean dependencies in a Spring configuration file. So all we need to do is enable annotation-driven injection to load the spring configuration.

@Configuration @ComponentScan("com.studentproject.autowireapp") 
public class AppConfig {
  // your code
}

But now, the Spring boot introduces the @SpringBootApplication annotation which is a combination of @Configuration@EnableAutoConfiguration, and @ComponentScan annotations and make it easy to use Auto-wiring in the Spring Boot application.

Here is an example:

@SpringBootApplication
public class WebappApplication {

public static void main(String[] args) {
  SpringApplication.run(WebappApplication.class, args);
  }
}


So this will lead to automatically scanning the components in the current package and its sub-packages.




When to use @Autowired Annotation in Spring? Examples

The @Autowired annotations can be used in many scenarios in spring boot. so let's have a look at the following attempts that the @Autowired can be used.
  • In Properties
  • In Setters
  • In Constructors
So let's discuss how we can use the @Autowired annotation in properties.

1. @Autowired on Properties.

So think you have a Student class and StudentService class in your project. If you want to use the student properties, then you need to use the setters and getters to retrieve those fields. But by using the @Autowired annotation, only you have to do is get the @Autowired on the field definition in StudentService class.


@Component("student")
public class Student {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}


So in the StudentService class, we can define the @Autowired annotation to get the Student
bean.

@Component
public class StudentService {
    @Autowired
    private Student student;
}


So this is a good example, which describes the Spring injects the Student when the  StudentService is created.




2. @Autowired on Setters

Adding the @Autowired annotation on the setter method, allows you to call the instance of Student when the StudentService is created.

public class StudentService {
    private Student student;

    @Autowired
    public void setStudent(Student student) {
        this.student = student;
    }
}



3. @Autowired on Constructors

So let's have a @Autowired annotation on a constructor and this will lead to creating an instance of Student on the StudentService Constructor.


public class StudentService {
    private Student student;
    
    @Autowired
    public StudentService(Student student) {
        this.student = student;
    }
}



3. @Autowired and optional dependencies

The @Autowired can be defined in the required type and it will lead to throwing an exception if the spring cannot resolve a bean for the wiring.


public class StudentService {

    @Autowired(required = false)
    private Student student;
}




So how does auto-wiring work in Spring?

Spring beans live inside a container which is called application context. Second, every program has a way to access that context. A Servlet is used in web applications, and JSF utilizes an el-resolver. In addition, the application context is bootstrapped, and all beans are auto-wired. This might be a starting listener in web applications.

Autowiring occurs when one bean's instance is inserted into the desired field of another bean's instance. Both classes should be beans, which means they should be declared to exist in the context of the application.

So what do we mean by "living" in the application context?. This means that the context instantiates the objects, not you. If you make the StudentService(), the container finds each injection point and sets an instance there.


// Defines that this class is a spring bean
@Controller
@RequestMapping("/students")
public class StudentController {

    // StudentService injects in here
    @Autowired
    private StudentService studentService;

    @RequestMapping("/student")
    public void getSpecificStudent(@RequestParam("studentId") String studentId) {

        // The StudentService is already injected and you can use it
        studentService.getSpecificStudent(studentId);

    }
}


Few things to remember when working with Autoworking and @Autowired in spring boot.

In your applicationContext.xml you should enable the so that classes are scanned for the @Controller, @Service, etc. annotations.

In your applicationContext.xml you should enable the so that classes are scanned for the @Controller, @Service, etc. annotations.

StudentService should likewise be declared as a bean, either with the @Service annotation or with the bean id=".." class="..">. It will be injected because it will be the sole UserService implementor.

Spring may utilize XML-configurable autowiring in addition to the @Autowired annotation. In such a scenario, any fields with a name or type that matches an existing bean will be injected with that bean. In reality, having fields injected with dependencies without any setup was the original notion behind auto-wiring. 

Other annotations, such as @Inject and @Resource, can be used as well.




Problems while using Autowiring in Spring

So let's have a problem which might occur at autowiring in spring.


Say, you have a service class called UserServiceImpl that implements the UserService interface.


How does this be @Autowired?

And in the Controllers, how would I instantiate an instance of this service?

UserService userService = new UserServiceImpl();


First, and most important - all Spring beans are managed - they "live" inside a container, which is called "application context"

Second, each application has an entry point to that context. Web applications have a Servlet, JSF uses an el-resolver, etc. Also, there is a place where the application context is bootstrapped and all beans - autowired. In web applications, this can be a startup listener.

Autowiring happens by placing an instance of one bean into the desired field in an instance
of another bean. Both classes should be beans, i.e. they should be defined to live in the
application context.

What is "living" in the application context? This means that the context instantiates the objects, not you. For example,  you never make new UserServiceImpl() - the container finds each injection point and sets an instance there.

In your controllers, you just have the following:

@Controller // Defines that this class is a spring bean
@RequestMapping("/users")
public class SomeController {

    // Tells the application context to inject an instance of UserService here
    @Autowired
    private UserService userService;

    @RequestMapping("/login")
    public void login(@RequestParam("username") String username,
        @RequestParam("password") String password) {

        // The UserServiceImpl is already injected and you can use it
        userService.login(username, password);

    }
}

A few notes:

In your applicationContext.xml you should enable the <context:component-scan> so that classes are scanned for the @Controller@Service, etc. annotations.

The entry point for a Spring-MVC application is the DispatcherServlet, but it is hidden from you, and hence the direct interaction and bootstrapping of the application context happens behind the scene.

UserServiceImpl should also be defined as bean - either using <bean id=".." class=".."> or using the @Service annotation. 

Since it will be the only implementor of UserService, it will be injected.



Apart from the @Autowired annotation, Spring can use XML-configurable autowiring. 

In that case, all fields that have a name or type that matches with an existing bean automatically get a bean injected. In fact, that was the initial idea of autowiring - to have fields injected with dependencies without any configuration. 

Other annotations like @Inject, @Resource can also be used.


That's all about how Autowring works in Spring Framework. I hope this tutorial will help you to understand both Autowiring and @Autowired annotations and you will be able to better use them and can read and understand existing code. So in this tutorial, we have discussed how does auto wiring work in spring with examples. This is an important concept in spring as this allows to inject beans into other classes as discussed above. So see you in the next tutorial.


Other Java and Spring Tutorial you may like
  • How to create your first Spring MVC application (tutorial)
  • Spring Boot + Reactjs example (example)
  • Spring Data JPA @Query Example (query example)
  • 20+ Spring MVC Interview Questions for Programmers (answer)
  • Top 5 Courses to Learn and Master Spring Cloud (courses)
  • What is @Conditional annotation in Spring? (conditional example)
  • 10 Advanced Spring Boot Courses for Java developers (courses)
  • Difference between @RequestParam and @PathVariable in Spring (answer)
  • Top 7  Courses to learn Microservices in Java (courses)
  • 13 Spring Boot Actuator Interview questions (boot questions)
  • Spring Data JPA Repository (JpaReposistory example)
  • How to update an entity using Spring Data JPA? (example)
  • How to use @Bean in Spring framework (Example)
  • Top 5 Frameworks Java Developer Should Know (frameworks)
  • How to upload and download files using Spring Boot (Example)
  • 10 Spring MVC annotations Java developer should know (annotations)
  • 5 Courses to Learn Spring Security for Java programmers (courses)
  • 5 Spring Cloud annotations Java programmer should learn (cloud)
  • 15 Spring Boot Interview Questions for Java Developers (questions)
  • Top 5 Spring Boot Annotations Java Developers should know (read)

Thanks for reading this article so far. If you find this Spring Framework Autowriing tutorial and @Autowrired annotation example then please share it with your friends and colleagues. If you have any questions or feedback, then please drop a note.

P. S. - If you are a beginner and want to learn the Spring Framework from scratch and look for some of the best online resources, you can also check out these best Spring Framework Courses. This list contains the best Udemy, Coursera, Educative, and Pluralsight courses to learn Spring Boot in depth.

No comments :

Post a Comment