This is another way to inject a short-lived scoped bean into long-lived scoped bean. For example injecting a prototype bean into a singleton bean.
We need to inject a proxy object that exposes the same public interface as the original scoped object.
Spring uses CGLIB to create the proxy object.
The proxy object delegates method calls to the real object.
Each access of underlying prototype object causes a new object to be created.
Example
Prototype bean
package com.logicbig.example;
import java.time.LocalDateTime;
public class MyPrototypeBean {
private String dateTimeString = LocalDateTime.now().toString();
public String getDateTime() {
return dateTimeString;
}
}
Singleton bean
package com.logicbig.example;
import org.springframework.beans.factory.annotation.Autowired;
public class MySingletonBean {
@Autowired
private MyPrototypeBean prototypeBean;
public void showMessage(){
System.out.println("Hi, the time is "+prototypeBean.getDateTime());
}
}
Main class Configuring the Scoped Proxy for Prototype bean
package com.logicbig.example;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyPrototypeBean prototypeBean () {
return new MyPrototypeBean();
}
@Bean
public MySingletonBean singletonBean () {
return new MySingletonBean();
}
public static void main (String[] args) throws InterruptedException {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class);
MySingletonBean bean = context.getBean(MySingletonBean.class);
bean.showMessage();
Thread.sleep(1000);
bean.showMessage();
}
}
OutputHi, the time is 2021-05-05T02:03:45.349 Hi, the time is 2021-05-05T02:03:46.372
In above example proxyMode=ScopedProxyMode.TARGET_CLASS causes an AOP proxy to be injected at the target injection point. The default proxyMode is ScopedProxyMode.NO .
Another possible value, ScopedProxyMode.INTERFACES creates JDK dynamic proxy (instead of class based CGLIB proxy) which can only take the target bean's interface types.
Example ProjectDependencies and Technologies Used: - spring-context 6.1.2 (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 6.1.2 Version compatibilities of spring-context with this example: Versions in green have been tested.
- JDK 17
- Maven 3.8.1
|