Spring @LookUp Annotation Example
In this section we will learn about @LookUp Annotation.
How to use @Lookup annotation
By default, the scope of the bean in a Spring application are singletons, and we use a constructor or setter to implement dependencies. But there is another situation: there is a singleton user, and he needs a new role bean every time. That is, User is a singleton bean, and Role is prototype bean. The life cycles of beans are different. Bean User is created by the container only once, and bean Role is created every time a new one is created – let's say this happens every time you call some method of the User bean. This is where the introduction of a bean using the @Lookup method comes in handy. It occurs not when the container is initialized, but later, each time the method is called.
A method annotated with @Lookup tells Spring to return an instance of the method's return type when we invoke it.
What is Lookup method injection?
Let's look at an example. Let's create a User class, a singleton, and make it a bean using the annotation @Component:
@Component
public class User {
@Lookup
public Role createRole() {
return null;
};
public String assignRole(String name) {
Role role = createRole();
role. setName(name);
return "User role is " + role. getName();
}
}
There is an assignRole() method in the bean, and each time the assignRole() method is called, the User bean requires a new instance of the Role bean– Role maybe Admin or Super User, it will change. That is, bean Role is prototype. To get this bean, you need to write the createRole() stub method to annotate it with @Lookup:
@Lookup
public Role createRole() {
return null;
};
The Spring container will override this stub method (createRole) and will issue a new Role instance each time it is called.
Define the bean Role as a prototype:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Role {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this. name = name;
}
}
And that's it, now when we call the assignRole() method, we can assign new role to the user.
The following example creates a Spring Boot application which uses @LookUp annotation.
Project Directory
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-lookup-annotation-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-lookup-annotation-example</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Role.java
package com.knf.dev.demo.component;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Role {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this. name = name;
}
}
User.java
package com.knf.dev.demo.component;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component
public class User {
@Lookup
public Role createRole() {
return null;
};
public String assignRole(String name) {
Role role = createRole();
role. setName(name);
return "User role is " + role. getName();
}
}
Run the application - Application.java
package com.knf.dev.demo;
import com.knf.dev.demo.component.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(Application.class, args);
User user = context. getBean(User. class);
System.out.println(user. assignRole("Admin"));
System.out.println( user. assignRole("Super User"));
context.close();
}
}
Application is the entry point that sets up the Spring Boot application. The @SpringBootApplication annotation enables auto-configuration and component scanning.
mvn spring-boot:run
User role is Admin
User role is Super User