Spring Boot @Autowired在运行时创建实例 [英] Spring Boot @Autowired creating instances on a runtime

查看:455
本文介绍了Spring Boot @Autowired在运行时创建实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为大多数Spring Boot新用户,我对@Autowired:D有疑问

As most of Spring Boot new users I have a problem with @Autowired :D

我在这里阅读了有关此批注的大量主题,但是仍然找不到解决我问题的合适方法.

I've readed a big amount of topics about this annotation here But still can't find proper solution for my problem.

假设我们具有以下Spring Boot层次结构:

Let's suppose that we have this Spring Boot hierarchy:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

类,每次调用时我们都要实例化:

Class, that we wanna instantiate every time it's called:

@Service
public class TestWire {
    public TestWire() {
        System.out.println("INSTANCE CREATED: " + this);
    }
}

输出get控制器,它将在每个请求中创建新的SomeRepo对象:

Out get controller, that creates new SomeRepo object every request:

@RestController
public class CreatingRepo {
    @RequestMapping("/")
    public void postMessage() {
        SomeRepo repo = new SomeRepo();
    }
}

最后,使用@Autowired创建TestWire实例的类:

Finally, class, that uses @Autowired to create TestWire instances:

public class SomeRepo {
    @Autowired
    private TestWire testWire;

    public SomeRepo() {
        System.out.println(testWire.toString());
    }
}

假设我们多次向"/"发出GET请求.

Let's assume, that we make GET request to "/" several times.

因此,结果是,TestWire类仅在项目构建时才会被验证,并且 @Scope(value ="prototype") proxyMode = ScopedProxyMode.TARGET_CLASS 都不会帮助.

So, as a result, TestWire class will isntantiate only when project builds and neither @Scope(value = "prototype"), nor proxyMode = ScopedProxyMode.TARGET_CLASS wont help.

有什么想法如何在运行时创建新实例?我的意思是,我们该如何以春天的方式"做到这一点?没有工厂和其他东西,只有Spring DI通过注释和配置.

Any ideas how to create new instances at runtime? I mean, how can we do it in "Spring way"? Without factories and other things, only Spring DI through annotation and configuration.

已更新.一条堆栈跟踪,其中创建了实例:

Upd. A piece of stack trace, where instance created:

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进行注释:

If I understood you correct you need to annotate the SomeRepo like this:

@Service
@Scope(value = "prototype")
public class SomeRepo { 
// ...
}

选项A:

您不是向BeanFactory.getBean(...)实例化类,而是向BeanFactory.getBean(...)询问.

Instead of instantiating the class with new SomeRepo(); you ask the BeanFactory.getBean(...) for it.

@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的参数):

You should also be able to get the Bean like this (over paramters without the 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 Boot @Autowired在运行时创建实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆