CommandLineRunner和Beans(Spring)

时间:2017-04-14 17:22:46

标签: spring

编码我的问题:

   @SpringBootApplication
public class Application {

    private static final Logger log = LoggerFactory.getLogger(Application.class);

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

    @Bean
    public Object test(RestTemplate restTemplate) {
        Quote quote = restTemplate.getForObject(
                "http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
        log.info(quote.toString());
        return new Random();
    }

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
        return builder.build();
    }

    @Bean
    public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
        return args -> {
            Quote quote = restTemplate.getForObject(
                    "http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
            log.info(quote.toString());
        };
    }
}

我对Spring很新。据我所知,@ Bean注释负责将对象保存在IoC容器中,对吗?

如果是这样的话:首先收集所有带@Bean的方法并执行然后吗?

在我的例子中,我添加了一个方法test(),它与run()相同,但返回一个Object(Random())。 结果是相同的,因此它使用CommandLineRunner和Object。

是否有理由返回CommandLineRunner,即使用run()这样的语法?

此外:到目前为止,我还没有看到将方法移动到容器的优势。为什么不执行呢?

谢谢!

1 个答案:

答案 0 :(得分:2)

@Configuration个类(@SpringBootApplication extends @Configuration)是注册spring bean的地方。 @Bean用于声明一个spring bean。用@Bean注释的方法必须返回一个对象(bean)。默认情况下,spring bean是单例,因此一旦执行了使用@Bean注释的方法并返回它的值,该对象将一直存在于应用程序的末尾。

在你的情况下

    @Bean
    public Object test(RestTemplate restTemplate) {
        Quote quote = restTemplate.getForObject(
                "http://gturnquist-quoters.cfapps.io/api/random", Quote.class);
        log.info(quote.toString());
        return new Random();
    }

这将产生一个名为' test'的Random类型的单例bean。因此,如果您尝试在其他spring bean中注入(例如使用@Autowire)该类型或名称的bean,您将获得该值。所以这不是@Bean注释的好用,除非你想要那样。

另一方面,

CommandLineRunner是一个特殊的bean,它允许您在加载和启动应用程序上下文后执行某些逻辑。所以在这里使用restTemplate是有意义的,调用url并打印返回的值。

不久前注册Spring bean的唯一方法是使用xml。所以我们有一个像这样的xml文件和bean声明:

<bean id="myBean" class="org.company.MyClass">
  <property name="someField" value="1"/>
</bean>

@Configuration类等同于xml文件,@Bean方法等同于<bean> xml元素。

因此,最好避免在bean方法中执行逻辑,并坚持创建对象并设置其属性。