0% found this document useful (0 votes)
2 views

SpringNotesByPawan

Uploaded by

Pawan Chavan
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

SpringNotesByPawan

Uploaded by

Pawan Chavan
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 15

The @Autowired annotation in Spring is used to automatically inject dependencies into a

class. In the Employee class, there are three main places where @Autowired can be applied:

1. Field Injection (Already Used in Your Code)

You’ve already used @Autowired on the address field in the Employee class. Here’s how it
works:

@Autowired
private Address address; // Dependency to be injected by Spring

Explanation:

 Spring will look for a bean of type Address in the application context and inject it
into the address field.
 This approach is simple and concise but makes the field difficult to test as it cannot be
set manually.

2. Setter Injection

You can use @Autowired on the setter method for the address field.

Code Example:

@Autowired
public void setAddress(Address address) {
this.address = address;
}

Explanation:

 Spring will call this setter method and pass the Address bean to it.
 Setter injection is useful when you want to allow optional dependencies or change the
dependency at runtime.

3. Constructor Injection

You can use @Autowired on the constructor of the Employee class.

Code Example:

@Autowired
public Employee(Address address) {
this.address = address;
}
Explanation:

 Spring will automatically inject the Address bean when creating the Employee bean.
 Constructor injection ensures that the dependency is provided at the time of object
creation, making the class immutable and easier to test.
 Preferred approach when the dependency is mandatory.

Full Example with All Three Types

Here’s how your Employee class could look with all three types of @Autowired usage:

package com.springcore.autowireannotation;

import org.springframework.beans.factory.annotation.Autowired;

public class Employee {


private String name;

@Autowired // Field Injection


private Address address;

public Employee() {}

@Autowired // Constructor Injection


public Employee(Address address) {
this.address = address;
}

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public Address getAddress() {


return address;
}

@Autowired // Setter Injection


public void setAddress(Address address) {
this.address = address;
}

@Override
public String toString() {
return "Employee [name=" + name + ", address=" + address + "]";
}
}

Which Approach Should You Use?

1. Constructor Injection:
o Preferred for mandatory dependencies.
o Ensures that the dependency is always initialized at the time of object creation.
2. Setter Injection:
o Useful for optional dependencies or when you need to reconfigure
dependencies at runtime.
3. Field Injection:
o Simplest but harder to test and less flexible compared to other approaches.

Recommended Usage for Your Example

For the Employee class, constructor injection is a good choice because the Address
dependency is likely mandatory for an Employee.

@Autowired
public Employee(Address address) {
this.address = address;
}

The @Qualifier annotation in Spring is used to resolve ambiguity when multiple beans of
the same type are available in the application context. It works in conjunction with
@Autowired to specify exactly which bean should be injected.

Why Do We Need @Qualifier?

When there are multiple beans of the same type, Spring does not know which one to inject.
This results in a NoUniqueBeanDefinitionException. The @Qualifier annotation provides
a way to explicitly specify the bean to be injected.

How Does It Work?

1. Define Multiple Beans of the Same Type:


Use @Bean or @Component to define multiple beans of the same type with unique
names.
2. Use @Qualifier:
Use @Qualifier alongside @Autowired to specify the exact bean to inject.

Example

1. Beans with the Same Type


Suppose you have two beans of type Address:

package com.springcore.autowireannotation;

import org.springframework.stereotype.Component;

@Component("homeAddress")
public class Address {
private String city = "New York";
private String state = "NY";

public String getFullAddress() {


return city + ", " + state;
}
}

@Component("officeAddress")
public class Address {
private String city = "Los Angeles";
private String state = "CA";

public String getFullAddress() {


return city + ", " + state;
}
}

2. Injecting with @Qualifier

In the Employee class, you can specify which Address bean to inject:

package com.springcore.autowireannotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class Employee {
private String name = "John Doe";

@Autowired
@Qualifier("homeAddress") // Specify the exact bean to inject
private Address address;

public void showEmployeeDetails() {


System.out.println("Employee: " + name);
System.out.println("Address: " + address.getFullAddress());
}
}

3. Configuration with XML

If you're using an XML configuration instead of annotations, you can achieve the same result:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="homeAddress"
class="com.springcore.autowireannotation.Address">
<property name="city" value="New York"/>
<property name="state" value="NY"/>
</bean>

<bean id="officeAddress"
class="com.springcore.autowireannotation.Address">
<property name="city" value="Los Angeles"/>
<property name="state" value="CA"/>
</bean>

<bean id="employee" class="com.springcore.autowireannotation.Employee">


<property name="address" ref="homeAddress"/> <!-- Specify the bean
-->
</bean>
</beans>

Output of the Example

When you run the application:

ApplicationContext context =
SpringApplication.run(AutowiredExampleApplication.class, args);

Employee employee = context.getBean(Employee.class);


employee.showEmployeeDetails();

Output:

Employee: John Doe


Address: New York, NY

Key Points about @Qualifier

1. Used with @Autowired:


o @Qualifier is always used in combination with @Autowired or similar
annotations like @Inject.
2. Bean Name Must Match:
o The value of @Qualifier must match the name of the target bean.
3. Avoids Ambiguity:
o It helps resolve ambiguity when multiple beans of the same type exist.
4. Can Be Used with Constructor Injection:
You can use @Qualifier in constructors:
5. @Autowired
6. public Employee(@Qualifier("homeAddress") Address address) {
7. this.address = address;
8. }
9. Can Be Used with Setter Injection:
10. @Autowired
11. public void setAddress(@Qualifier("homeAddress") Address address) {
12. this.address = address;
13. }

Advantages of @Qualifier

 Fine-Grained Control: Allows precise control over bean injection.


 Readability: Makes it clear which bean is being injected.
 Avoids Errors: Prevents NoUniqueBeanDefinitionException in scenarios with
multiple beans.

When to Use @Qualifier

 When you have multiple beans of the same type.


 When you want to make your code more explicit and easier to understand.

This ensures your application works as expected without ambiguity, even in complex
dependency injection scenarios.

Stand Alone Collection in spring

Spring Standalone Collections

Spring allows the configuration of collections (e.g., List, Set, Map, and Properties)
directly in the Spring configuration file. These are called "Standalone Collections" because
they can be defined as independent beans and injected into other beans.

1. List Example

A List is an ordered collection of elements.

XML Configuration

<bean id="employeeList" class="java.util.ArrayList">


<constructor-arg>
<list>
<value>John</value>
<value>Jane</value>
<value>Doe</value>
</list>
</constructor-arg>
</bean>
Bean Class

import java.util.List;

public class EmployeeService {


private List<String> employees;

public void setEmployees(List<String> employees) {


this.employees = employees;
}

public void displayEmployees() {


System.out.println("Employees: " + employees);
}
}

Main Application

ApplicationContext context = new


ClassPathXmlApplicationContext("beans.xml");
EmployeeService employeeService = context.getBean(EmployeeService.class);
employeeService.displayEmployees();

Output

Employees: [John, Jane, Doe]

2. Set Example

A Set is a collection that does not allow duplicate elements.

XML Configuration

<bean id="uniqueNames" class="java.util.HashSet">


<constructor-arg>
<set>
<value>Apple</value>
<value>Banana</value>
<value>Apple</value>
</set>
</constructor-arg>
</bean>

Bean Class

import java.util.Set;

public class FruitService {


private Set<String> fruits;

public void setFruits(Set<String> fruits) {


this.fruits = fruits;
}

public void displayFruits() {


System.out.println("Fruits: " + fruits);
}
}

Main Application

ApplicationContext context = new


ClassPathXmlApplicationContext("beans.xml");
FruitService fruitService = context.getBean(FruitService.class);
fruitService.displayFruits();

Output

Fruits: [Apple, Banana]

3. Map Example

A Map is a collection of key-value pairs.

XML Configuration

<bean id="countryCapitalMap" class="java.util.HashMap">


<constructor-arg>
<map>
<entry key="USA" value="Washington D.C." />
<entry key="India" value="New Delhi" />
<entry key="UK" value="London" />
</map>
</constructor-arg>
</bean>

Bean Class

import java.util.Map;

public class CountryService {


private Map<String, String> countryCapitalMap;

public void setCountryCapitalMap(Map<String, String> countryCapitalMap)


{
this.countryCapitalMap = countryCapitalMap;
}

public void displayCountryCapitals() {


countryCapitalMap.forEach((country, capital) ->
System.out.println(country + " -> " + capital)
);
}
}

Main Application

ApplicationContext context = new


ClassPathXmlApplicationContext("beans.xml");
CountryService countryService = context.getBean(CountryService.class);
countryService.displayCountryCapitals();
Output

USA -> Washington D.C.


India -> New Delhi
UK -> London

4. Properties Example

A Properties object is a collection of key-value pairs, typically used for configuration


settings.

XML Configuration

<bean id="dbProperties" class="java.util.Properties">


<constructor-arg>
<props>
<prop key="url">jdbc:mysql://localhost:3306/mydb</prop>
<prop key="username">root</prop>
<prop key="password">password</prop>
</props>
</constructor-arg>
</bean>

Bean Class

import java.util.Properties;

public class DatabaseConfig {


private Properties dbProperties;

public void setDbProperties(Properties dbProperties) {


this.dbProperties = dbProperties;
}

public void displayDbProperties() {


dbProperties.forEach((key, value) ->
System.out.println(key + " = " + value)
);
}
}

Main Application

ApplicationContext context = new


ClassPathXmlApplicationContext("beans.xml");
DatabaseConfig databaseConfig = context.getBean(DatabaseConfig.class);
databaseConfig.displayDbProperties();

Output

url = jdbc:mysql://localhost:3306/mydb
username = root
password = password
Standalone Collections as Dependencies

You can also inject these collections into other beans:

XML Configuration

<bean id="employeeService" class="com.example.EmployeeService">


<property name="employees" ref="employeeList" />
</bean>

Bean Class

public class EmployeeService {


private List<String> employees;

public void setEmployees(List<String> employees) {


this.employees = employees;
}

public void displayEmployees() {


System.out.println("Employees: " + employees);
}
}

Key Points

1. Type of Collections: Supported types include List, Set, Map, and Properties.
2. Reusability: Collections can be defined as standalone beans for reusability.
3. Dynamic Initialization: Allows dynamic configuration of collections in XML or
Java-based configurations.

This makes Spring highly flexible and powerful for managing collection-based dependencies.

Example

Here's the updated Java code and XML configuration file. The code now includes standalone
Map, Set, and LinkedList, and the XML configuration file is modified to reflect these
additions.

// Java Code

package com.springcore.standalone.collection;

import java.util.*;

public class Person {


private List<String> friends;

private Set<String> favoriteBooks;

private Map<String, String> addressMap;

private LinkedList<String> recentActivities;

public List<String> getFriends() {

return friends;

public void setFriends(List<String> friends) {

this.friends = friends;

public Set<String> getFavoriteBooks() {

return favoriteBooks;

public void setFavoriteBooks(Set<String> favoriteBooks) {

this.favoriteBooks = favoriteBooks;

public Map<String, String> getAddressMap() {

return addressMap;

}
public void setAddressMap(Map<String, String> addressMap) {

this.addressMap = addressMap;

public LinkedList<String> getRecentActivities() {

return recentActivities;

public void setRecentActivities(LinkedList<String> recentActivities) {

this.recentActivities = recentActivities;

@Override

public String toString() {

return "Person [friends=" + friends + ", favoriteBooks=" + favoriteBooks + ",


addressMap=" + addressMap + ", recentActivities=" + recentActivities + "]";

Updated XML Configuration File:


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">

<!-- Standalone List -->


<util:list list-class="java.util.ArrayList" id="mybestfriends">
<value>Aman</value>
<value>Raman</value>
<value>Mohan</value>
</util:list>

<!-- Standalone Set -->


<util:set set-class="java.util.HashSet" id="myfavoritebooks">
<value>The Alchemist</value>
<value>1984</value>
<value>To Kill a Mockingbird</value>
</util:set>

<!-- Standalone Map -->


<util:map map-class="java.util.HashMap" id="myaddressmap">
<entry key="Home" value="123 Main Street" />
<entry key="Office" value="456 Elm Street" />
</util:map>

<!-- Standalone LinkedList -->


<util:list list-class="java.util.LinkedList" id="recentactivities">
<value>Jogging</value>
<value>Reading</value>
<value>Coding</value>
</util:list>

<!-- Define the bean for Person -->


<bean class="com.springcore.standalone.collection.Person"
name="person1">
<property name="friends" ref="mybestfriends" />
<property name="favoriteBooks" ref="myfavoritebooks" />
<property name="addressMap" ref="myaddressmap" />
<property name="recentActivities" ref="recentactivities" />
</bean>

</beans>

Explanation:

1. Java Code Updates:


o Added Set<String> for favorite books.
o Added Map<String, String> for addresses.
o Added LinkedList<String> for recent activities.

2. XML Configuration:
o Defined util:set, util:map, and util:list for favoriteBooks,
addressMap, and recentActivities.
o Updated the Person bean to inject these collections using the appropriate
references.

You can now use this updated code and configuration to work with multiple standalone
collections in your Spring application.
Here’s an example of using the @Component annotation with a Student class in Spring.

Student Class with @Component


package com.example;

import org.springframework.stereotype.Component;

@Component
public class Student {
private String name = "John Doe";
private int age = 20;

public String getName() {


return name;
}

public void setName(String name) {


this.name = name;
}

public int getAge() {


return age;
}

public void setAge(int age) {


this.age = age;
}

@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}

Configuration Class
package com.example;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}

Main Class to Test


package com.example;

import org.springframework.context.ApplicationContext;
import
org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp {


public static void main(String[] args) {
// Create the application context
ApplicationContext context = new
AnnotationConfigApplicationContext(AppConfig.class);

// Retrieve the Student bean


Student student = context.getBean(Student.class);

// Use the Student bean


System.out.println(student);
}
}

Explanation

1. @Component: The Student class is annotated with @Component, which makes it a Spring-
managed bean.
2. @ComponentScan: In AppConfig, the @ComponentScan annotation ensures that Spring
scans the specified package (com.example) to find and register all @Component annotated
classes.
3. Application Context: The AnnotationConfigApplicationContext loads the
configuration and scans for components.

Output

When you run the MainApp class, you should see the following output:

Student [name=John Doe, age=20]

This demonstrates how @Component simplifies bean declaration and enables Spring to
automatically manage the Student class as a bean.

Collection with @Value

Bean Scope

You might also like