简体   繁体   English

在 Spring Boot 中检索 bean?

[英]Retrieving beans in Spring Boot?

I've worked with legacy Spring in the past.我过去曾与传统 Spring 合作过。 We defined our beans via xml configuration and manually wired them.我们通过 xml 配置定义了我们的 bean 并手动连接它们。 My team is finally making a concerted effort to update to annotations and use Spring Boot instead of the 'traditional' approach with Spring MVC.我的团队终于齐心协力更新注释并使用 Spring Boot 而不是 Spring MVC 的“传统”方法。

With that said, I cannot figure out how the heck I retrieve a bean in Boot.话虽如此,我无法弄清楚我是如何在 Boot 中检索 bean 的。 In legacy, Spring would either use constructor/setter injection (depending on our configuration), or we could directly call a bean with context.getBean("myBeanID");在旧版中,Spring 要么使用构造函数/setter 注入(取决于我们的配置),要么我们可以使用context.getBean("myBeanID");直接调用 bean context.getBean("myBeanID"); However, it does not appear to be the case anymore.然而,现在情况似乎不再如此。

I put together a small test case to try and get this working in the below code:我整理了一个小测试用例来尝试在下面的代码中让它工作:

package com.ots;


import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class GriefUIApplication{

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

        SessionFactory factory = new Configuration().configure("hibernate.cfg.xml")
                .addAnnotatedClass(GriefRecord.class).addAnnotatedClass(RecordId.class)
                .addAnnotatedClass(CrossReferenceRecord.class)
                .buildSessionFactory();

        Statics.setSessionFactory(factory);

        TennisCoach tCoach = new TennisCoach();
        tCoach.getCoach();

    }

}



interface Coach{
    public String workout();
}


@Service
class TennisCoach implements Coach{

    private Coach soccerCoach;
    @Autowired
    private ApplicationContext context;


    public TennisCoach() {

    }

    public Coach getCoach() {

        System.out.println(context + " IS THE VALUE OF THE CONTEXT OBJECT");

        soccerCoach = (SoccerCoach)context.getBean("soccerCoach");

        System.out.println(soccerCoach.getClass());

        return soccerCoach;

    }

    @Override
    public String workout() {
        String practice = "practice your backhand!";
        System.out.println(practice);
        return practice;
    }


}

@Service
class SoccerCoach implements Coach{

    public SoccerCoach() {

    }

    @Override
    public String workout() {
        String practice = "practice your footwork!";
        System.out.println(practice);
        return practice;
    }

}

@RestController
class MyController{

    @GetMapping("/")
    public String sayHello() {

        return "Time on server is: " + new java.util.Date();
    }

}

I tried autowiring the ApplicationContext object into the TennisCoach class.我尝试将 ApplicationContext 对象自动装配到 TennisCoach 类中。 When I run this, that object is null.当我运行它时,该对象为空。

How do we retrieve beans in Boot?我们如何在 Boot 中检索 bean?

The most common approach is to use the @Autowired annotation.最常见的方法是使用@Autowired注释。 Also, because you have two different implementations of the Coach interface, you should use the @Qualifier annotation to tell Spring which interface implementation to inject.此外,因为您有两个不同的Coach接口实现,您应该使用@Qualifier注释来告诉 Spring 要注入哪个接口实现。

Some tutorials about these two annotations, to get you started:有关这两个注释的一些教程,以帮助您入门:

For your example, to inject the beans into your controller, you should do:对于您的示例,要将 bean 注入控制器,您应该执行以下操作:

@RestController
class MyController {

    @Autowired
    @Qualifier("soccerCoach")
    private Coach coach;

    @GetMapping("/")
    public String sayHello() {
        // this should invoke the workout() from SoccerCoach implementation
        System.out.println(coach.workout());

        return "Time on server is: " + new java.util.Date();
    }

}

Or, to inject the soccerCoach into the tennisCoach as you intended, using constructor injection , the code would become:或者,按照您的意图将soccerCoach注入到tennisCoach中,使用构造函数注入,代码将变为:

@Service
class TennisCoach implements Coach {

    private Coach soccerCoach;

    @Autowired
    public TennisCoach(@Qualifier("soccerCoach") Coach soccerCoach) {
        this.soccerCoach = soccerCoach;
    }

    public Coach getCoach() {
        System.out.println(soccerCoach.getClass());

        return soccerCoach;
    }

}

If you really need to use the ApplicationContext to retrieve some bean, it's not advisable to do so in your class that has the main function.如果您确实需要使用ApplicationContext来检索某个 bean,则不建议在具有main函数的类中这样做。 Just create another bean (you could use the @Componenent annotation).只需创建另一个 bean(您可以使用@Componenent批注)。 Here's an example:下面是一个例子:

@Component
public class AnyComponent {

    @Autowired
    private ApplicationContext applicationContext;

    public void invokeCoach() {
        System.out.println(applicationContext.getBean("tennisCoach"));
        System.out.println(applicationContext.getBean(SoccerCoach.class));
    }

}

And inject this bean in your application flow, could be in the controller, service, or repository:并在您的应用程序流中注入这个 bean,可以在控制器、服务或存储库中:

@RestController
class MyController {

    @Autowired
    private AnyComponent anyComponent;

    @GetMapping("/")
    public String sayHello() {
        anyComponent.invokeCoach();

        return "Time on server is: " + new java.util.Date();
    }

}

Note: Injecting beans through annotation is something specific to Spring, in general, not Spring Boot in particular.注意:通过注解注入 bean 是 Spring 特有的,一般来说,不是 Spring Boot 特有的。

From https://www.baeldung.com/spring-autowire :https://www.baeldung.com/spring-autowire

Starting with Spring 2.5, the framework introduced a new style of Dependency Injection driven by @Autowired Annotations.从 Spring 2.5 开始,该框架引入了一种由 @Autowired Annotations 驱动的新风格的依赖注入。 This annotation allows Spring to resolve and inject collaborating beans into your bean.这个注解允许 Spring 解析并将协作 bean 注入到您的 bean 中。

Inject the required beans directly.直接注入需要的bean。 No need of ApplicationContext in Spring boot. Spring boot 中不需要ApplicationContext

@Service
class TennisCoach {

    private SoccerCoach soccerCoach;

    @Autowired
    public TennisCoach(SoccerCoach soccerCoach) {
      this.soccerCoach = soccerCoach;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM