简体   繁体   English

将YML / Java配置自动装配到Spring Boot Bean中

[英]Autowiring YML/Java Configuration into a Spring Boot Bean

If I have a application.yml that looks like 如果我有一个看起来像的application.yml

system:
  props:
    version: 1.0.0
    host: myhost
  myapp:
    environment: LOCAL

---
spring:
  profiles: DEV
system:
  myapp:
    environment: DEV
devhost: mydevhost

---
spring:
  profiles: PROD
system:
  myapp:
    environment: PROD
testhost: myprodhost

And I set up a config class using 我使用设置了一个配置类

@Configuration
@EnableConfigurationProperties
@ConfigurationProperties
public class MyConfig { 
private string devhost;
:
:
public String getDevHost() {return devhost;}
}

Am I able to autowire MyConfig into a class that is an annotated bean of a class that looks like 我能够将MyConfig自动装配到一个类中,该类是一个看起来像类的类的注释bean

@Configuration
@EnableJms
public class MyOtherConfig { 
@Bean
 public Object beanThatNeedsMyConfig(){return new beanThatNeedsMyConfig();}
 }

I tried using my intuition and Autowired it in beanThatNeedsMyConfig() and I'm calling on it by saying myConfig.getDevHost() , but I'm getting a null pointer as myConfig is null. 我尝试使用我的直觉并在beanThatNeedsMyConfig()beanThatNeedsMyConfig()调用它,我通过说myConfig.getDevHost()调用它,但是当myConfig为null时,我得到一个空指针。 I'm assuming Spring has yet to acknowledge it's existence. 我认为Spring还没有承认它的存在。 I'm still working on grasping Spring Boot and lifecycles, etc, etc. Any knowledge on how I can accomplish this? 我还在努力抓住Spring Boot和生命周期等等。有关如何实现这一目标的任何知识?

So, what is happening in your original code is that you're not autowiring anything into your bean that needs configuration . 因此,原始代码中发生的事情是,您不需要将任何内容自动装配到bean that needs configurationbean that needs configuration When you do this: 当你这样做:

@Bean
public Object beanThatNeedsMyConfig(){return new beanThatNeedsMyConfig();}}

You're not passing the MyConfig bean into the bean that needs it. 您没有将MyConfig bean传递给需要它的bean Autowiring is wonderful, but its not magick. 自动装配是美妙的,但它并不神奇。 To pass it in you should autowire it into the MyOtherConfig class, or you should remove the beanThatNeedsMyConfig() method completely which would allow spring to create the bean and do the autowiring automagically. 要传递它,你应该将它自动装入MyOtherConfig类,或者你应该完全删除beanThatNeedsMyConfig()方法,这将允许spring创建bean并自动进行自动装配。

Btw: The @Inject annotation should really only be used on constructors, any anyone who tells you differently is lying to you. 顺便说一下: @Inject注释应该只用于构造函数,任何以不同方式告诉你的人都会对你撒谎。 If you had it on the constructor for BeanThatNeedsMyConfig , you'd have not been able to construct it without passing the object in and your problem would have been self evident. 如果你在BeanThatNeedsMyConfig的构造函数中使用BeanThatNeedsMyConfig ,你将无法在不传递对象的情况下构造它,并且你的问题本身就是明显的。

Review the Spring Boot docs( structure and autoconfiguration of beans ). 查看Spring Boot文档( bean的 结构自动配置 )。

In general, it's easiest to put your SpringBootApplication at the root of your package hierachy (eg com.example.myapp ), then extend as needed (eg com.example.myapp.model ). 通常,最简单的方法是将SpringBootApplication放在包层的根部(例如com.example.myapp ),然后根据需要进行扩展(例如com.example.myapp.model )。 If you do this, you don't have to do anything other than annotate your Application with SpringBootApplication for a basic application. 如果这样做,除了使用SpringBootApplication为基本应用程序注释Application之外,您不必执行任何操作。 You may need other annotations for additional features, like EnableJpaRepositories . 您可能需要其他注释来获取其他功能,例如EnableJpaRepositories

If you structure your code as suggested above (locating your application class in a root package), you can add @ComponentScan without any arguments. 如果按照上面的建议构建代码(在根包中定位应用程序类),则可以添加不带任何参数的@ComponentScan。 All of your application components (@Component, @Service, @Repository, @Controller etc.) will be automatically registered as Spring Beans. 所有应用程序组件(@ Component,@ Service,@ Repository,@ Controller等)都将自动注册为Spring Beans。

'Automatically registered as Spring Beans' means you don't need to define an @Bean method that uses the default or an Autowired constructor. '自动注册为Spring Beans'意味着您不需要定义使用默认或Autowired构造函数的@Bean方法。 These are automatically provided for you. 这些是自动为您提供的。 You only need to explicitly define @Bean methods for things you need to configure manually, such as something from a custom Builder object. 您只需要为需要手动配置的事物显式定义@Bean方法,例如来自自定义Builder对象的内容。

So it would seem that inside the class of 所以它似乎在类的内部

@Bean
public Object beanThatNeedsMyConfig()

it just doesn't seem to know about MyConfig at all with it autowired up. 它似乎根本不知道关于MyConfig自动装配。 However, if I move the autowired object to MyOtherConfig (the class with all the annotated beans), it exists and I am able to use the properties from the .yml, all I have to do is just pass the autowired myConfig to the class that needed it and it works. 但是,如果我将自动装配的对象移动到MyOtherConfig (带有所有带注释的bean的类),它就存在并且我能够使用.yml中的属性,我所要做的就是将自动装配的myConfig传递给类需要它,它的工作原理。

If anyone wants to add a comment to my answer (or pose a whole new answer) to elaborate on why Spring knows about it in my main configuration class with my beans, and not inside the bean itself, I'm sure it could prove to be valuable information to others 如果有人想在我的答案中添加评论(或提出一个全新的答案)来详细说明为什么Spring在我的主要配置类中使用我的bean知道它,而不是在bean本身内部,我相信它可以证明是对他人有价值的信息

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

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