Spring 3.0, started supporting JSR-330 standard annotations (Dependency Injection). That means now we can use @javax.inject.Inject instead of @Autowire along with other standard annotations and interfaces.
To solve shorter-lived scoped bean injection problem (tutorial), we now have a standard option, i.e. using javax.inject.Provider<T> interface:
The Provider interface
package javax.inject;
........
public interface Provider<T> {
....
T get();
}
In Spring application we can inject Provider<T> :
@Autowired
private Provider<MyPrototypeBean> myPrototypeBeanProvider;
According to the specification, Provider.get() will always return the new instance of MyPrototypeBean.
We won't need any other extra configuration in @Configuration class. We just have to return instance of MyPrototypeBean bean from one of the factory method, annotated with @Bean.
Having this interface injected has other advantages as well e.g. lazy retrieval of an instance etc.
The good thing is, this approach doesn't involve any runtime byte code generation but it's just like Spring's ObjectFactory implementation. ObjectFactory is Spring specific alternative to Provider interface. In the following example with can replace Provider with ObjectFactory without any other change.
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;
import javax.inject.Provider;
public class MySingletonBean {
@Autowired
private Provider<MyPrototypeBean> myPrototypeBeanProvider;
public void showMessage () {
MyPrototypeBean bean = myPrototypeBeanProvider.get();
System.out.println("Hi, the time is " + bean.getDateTime());
}
}
Configuration and Main class
package com.logicbig.example;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class AppConfig {
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
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 = context.getBean(MySingletonBean.class);
bean.showMessage();
}
}
OutputHi, the time is 2021-05-05T23:53:10.245 Hi, the time is 2021-05-05T23:53:11.266
Example ProjectDependencies and Technologies Used: - spring-context 5.3.23 (Spring Context)
Version Compatibility: 3.2.3.RELEASE - 5.3.23
- javax.inject 1 (The javax.inject API)
- JDK 8
- Maven 3.8.1
|