Spring Boot @Autowired 在运行时创建实例
Spring Boot @Autowired creating instances on a runtime
作为大多数 Spring 引导新用户,我对 @Autowired 有疑问:D
我在这里阅读了大量关于此注释的主题,但仍然找不到适合我的问题的解决方案。
假设我们有这个 Spring 引导层次结构:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Class,我们想在每次调用时实例化它:
@Service
public class TestWire {
public TestWire() {
System.out.println("INSTANCE CREATED: " + this);
}
}
Out get controller,它在每次请求时创建新的 SomeRepo 对象:
@RestController
public class CreatingRepo {
@RequestMapping("/")
public void postMessage() {
SomeRepo repo = new SomeRepo();
}
}
最后,class,它使用@Autowired 创建 TestWire 实例:
public class SomeRepo {
@Autowired
private TestWire testWire;
public SomeRepo() {
System.out.println(testWire.toString());
}
}
假设我们多次向“/”发出 GET 请求。
因此,TestWire class 仅在项目构建时才会实例化,@Scope(value = "prototype") 和 proxyMode = ScopedProxyMode.TARGET_CLASS 不会有帮助。
知道如何在运行时创建新实例吗?我的意思是,我们如何才能在 "Spring way" 中做到这一点?没有工厂和其他东西,只有 Spring DI 通过注解和配置。
更新。一段堆栈跟踪,创建实例的位置:
2015-11-16 20:30:41.032 INFO 17696 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
INSTANCE CREATED: com.example.TestWire@56c698e3
2015-11-16 20:30:41.491 INFO 17696 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@12f41634: startup date [Mon Nov 16 20:30:37 MSK 2015]; root of context hierarchy
2015-11-16 20:30:41.566 INFO 17696 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public void com.example.CreatingRepo.postMessage()
如果我理解你是对的,你需要像这样注释 SomeRepo
:
@Service
@Scope(value = "prototype")
public class SomeRepo {
// ...
}
选项A:
不是用 new SomeRepo();
实例化 class,而是向 BeanFactory.getBean(...)
请求它。
@RestController
public class CreatingRepo {
@Autowired
BeanFactory beanFactory;
@RequestMapping("/")
public void postMessage() {
// instead of new SomeBean we get it from the BeanFactory
SomeRepo repo = beanFactory.getBean(SomeRepo.class);
}
}
选项B:
您也应该能够像这样获得 Bean(在没有 beanFactory
的参数上):
@RestController
public class CreatingRepo {
@RequestMapping("/")
public void postMessage(SomeRepo repo) {
// instead of the BeanFactory and using new SomeRepo you can get it like this.
}
}
作为大多数 Spring 引导新用户,我对 @Autowired 有疑问:D
我在这里阅读了大量关于此注释的主题,但仍然找不到适合我的问题的解决方案。
假设我们有这个 Spring 引导层次结构:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Class,我们想在每次调用时实例化它:
@Service
public class TestWire {
public TestWire() {
System.out.println("INSTANCE CREATED: " + this);
}
}
Out get controller,它在每次请求时创建新的 SomeRepo 对象:
@RestController
public class CreatingRepo {
@RequestMapping("/")
public void postMessage() {
SomeRepo repo = new SomeRepo();
}
}
最后,class,它使用@Autowired 创建 TestWire 实例:
public class SomeRepo {
@Autowired
private TestWire testWire;
public SomeRepo() {
System.out.println(testWire.toString());
}
}
假设我们多次向“/”发出 GET 请求。
因此,TestWire class 仅在项目构建时才会实例化,@Scope(value = "prototype") 和 proxyMode = ScopedProxyMode.TARGET_CLASS 不会有帮助。
知道如何在运行时创建新实例吗?我的意思是,我们如何才能在 "Spring way" 中做到这一点?没有工厂和其他东西,只有 Spring DI 通过注解和配置。
更新。一段堆栈跟踪,创建实例的位置:
2015-11-16 20:30:41.032 INFO 17696 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
INSTANCE CREATED: com.example.TestWire@56c698e3
2015-11-16 20:30:41.491 INFO 17696 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@12f41634: startup date [Mon Nov 16 20:30:37 MSK 2015]; root of context hierarchy
2015-11-16 20:30:41.566 INFO 17696 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public void com.example.CreatingRepo.postMessage()
如果我理解你是对的,你需要像这样注释 SomeRepo
:
@Service
@Scope(value = "prototype")
public class SomeRepo {
// ...
}
选项A:
不是用 new SomeRepo();
实例化 class,而是向 BeanFactory.getBean(...)
请求它。
@RestController
public class CreatingRepo {
@Autowired
BeanFactory beanFactory;
@RequestMapping("/")
public void postMessage() {
// instead of new SomeBean we get it from the BeanFactory
SomeRepo repo = beanFactory.getBean(SomeRepo.class);
}
}
选项B:
您也应该能够像这样获得 Bean(在没有 beanFactory
的参数上):
@RestController
public class CreatingRepo {
@RequestMapping("/")
public void postMessage(SomeRepo repo) {
// instead of the BeanFactory and using new SomeRepo you can get it like this.
}
}