In this post under Spring Core, I will explain with example the purpose of “@Lookup” annotation used without any arguments.
“@Lookup” annotation is applied only on methods.
“@Lookup” annotation can be used with or without arguments.
In this post I will show how to use “@Lookup” annotation without arguments.
In case of “@Lookup” annotation without arguments, the annotation tells spring to create an instance of a type, which is used as a return type in annotated method.
Basically it calls Spring applicationContext’s “getBean” method with return type of “@Lookup” annotated method as type argument to “getBean” method.
Please note “@Lookup” annotation works only with “@Component” annotation and not with “@Bean” annotation.
So for example, if we have below method
@Lookup
public ContainedBean createContainedBean() {
return null;
}
This tells the Spring to override the default implementation of method “createContainedBean” in such a way that it returns an instance of “ContainedBean” every time this method is called.
The method to be annotated with “@Lookup” annotation can be abstract or have a default implementation.
“@Lookup” annotation is basically used to injecting beans programmatically instead of declaratively.
Lets say we have two classes “ContainerBean” and “ContainedBean”.
“ContainerBean” is a Singleton bean whereas “ContainedBean” is a prototype bean.
“ContainerBean” is dependent on “ContainedBean”.
Below are the class structure of both of them
ContainerBean
package core.package42;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ContainerBean {
@Autowired
private ContainedBean1 containedBean;
public void display() {
containedBean.display();
}
}
ContainedBean
package core.package42;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class ContainedBean {
private static int instanceCount = 0;
private int id;
public ContainedBean() {
id = instanceCount;
instanceCount = instanceCount + 1;
}
public void display() {
System.out.println("Instance Id: " + id);
}
}
In normal scenario “ContainerBean” is initialized and along with an instance of “ContainedBean” with id say 1 is also initialized.
Whenever “display” method of “ContainerBean” instance is called, Spring instead of creating new instance of “ContainedBean” it uses the same instance of “ContainedBean” (i.e., bean with id 1).
This can be changed by modifying the class structure of “ContainerBean” as shown below
ContainerBean
package core.package42;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component
public class ContainerBean {
public void display() {
ContainedBean containedBean = createContainedBean();
containedBean.display();
}
@Lookup
public ContainedBean createContainedBean() {
return null;
}
}
Spring overrides the default implementation of “createContainedBean” in such a way that it creates a new instance of “ContainedBean” whenever this method is called.
Now whenever we call “display” method of “ContainerBean”, a new instance of “ContainedBean” is created and its “display” method is called.
Below is the complete main class for your reference
Main class
package core.package42;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "core.package42")
public class Example42 {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Example42.class);
ContainerBean containerBean = applicationContext.getBean("containerBean", ContainerBean.class);
containerBean.display();
containerBean.display();
containerBean.display();
}
}
Below is the output
Output
Instance Id: 0
Instance Id: 1
Instance Id: 2
In this way we can use “@Lookup” annotation without arguments.