2016-07-21 2 views
3

Если у меня есть application.yml, который выглядит какYML автоматического связывания/конфигурации Java в Spring Bean загрузки

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 

И я создал класс конфигурации, используя

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

Умею autowire MyConfig в класс, который является аннотированным бобом класса, который выглядит как

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

Я попытался с помощью своей интуиции и Autowired его в beanThatNeedsMyConfig(), и я вызываю его, говоря myConfig.getDevHost(), но я получаю нулевой указатель, поскольку myConfig имеет значение NULL. Я предполагаю, что Весна еще не признала существование. Я все еще работаю над тем, чтобы схватить Spring Boot и жизненные циклы и т. Д. И т. Д. Любые знания о том, как я могу это сделать?

ответ

2

Итак, что происходит в вашем исходном коде, так это то, что вы ничего не делаете в своем bean that needs configuration. Когда вы сделаете это:

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

Вы не передавая MyConfig боб в bean, что в ней нуждается. Автомагазин замечательный, но его не магия.Чтобы передать его, вы должны автоустанавливать его в класс MyOtherConfig, или вы должны полностью удалить метод beanThatNeedsMyConfig(), который позволил бы пружине создать компонент и автомассировать автоматически.

Btw: Аннотации @Inject действительно должны использоваться только для конструкторов, любой, кто говорит вам по-другому, лжет вам. Если бы у вас это было на конструкторе для BeanThatNeedsMyConfig, вы бы не смогли его построить, не передав объект, и ваша проблема была бы очевидна.

+0

Я вижу. Приятно знать, что я был в правильном направлении мышления, хотя я не знал техник. Я сделал именно то, что вы предложили в моем ответе ниже. Поместите его в «MyOtherConfig» и передайте его как параметр. Хорошо, чтобы мое решение было подтверждено. –

+0

Прохладный. Теперь не позволяйте мне поймать, что вы делаете это снова;) –

0

Так что, казалось бы, что внутри класса

@Bean 
public Object beanThatNeedsMyConfig() 

это просто, кажется, не знает о MyConfig вообще с ним autowired вверх. Однако, если я перемещаю объект с автоопределением на MyOtherConfig (класс со всеми аннотированными компонентами), он существует, и я могу использовать свойства из .yml, все, что мне нужно сделать, это просто передать автоуведомленный myConfig классу, который он нужен, и он работает.

Если кто-то хочет добавить комментарий к моему ответу (или представить новый ответ), чтобы выяснить, почему Spring знает об этом в моем основном классе конфигурации с моими бобами, а не внутри самого компонента, я уверен это может оказаться ценной информацией для других.

+1

Вопрос в том, что классы, которые нуждаются в 'MyConfig' и объявляют метод beanThatNeedsMyConfig(), похожим (аннотация)? Правильно ли ваш класс @ @ SpringBootApplication? Является ли это в родительском пакете вышеуказанных классов? С приложением Spring Boot, где классы и как они открыты, важно. Это часто определяет, найден ли 'Bean' или нет. – JudgingNotJudging

+1

Кроме того, если ваш метод '@ Bean' просто вызывает конструктор по умолчанию, вам не нужно определять этот метод. Пока класс, который вы пытаетесь объявить как bean, аннотируется с помощью какого-либо производного '@ Component', Spring Boot найдет его для вас. – JudgingNotJudging

+0

@JudgingNotJudging Я вижу, что все имеет смысл, я не знал о лакомых кусочках о том, где расположены классы и как их обнаруживают. Вам посчастливилось иметь ссылку, описывающую это, или поразмыслить над этим дальше? –

1

Просмотрите документы весенней загрузки (structure и autoconfiguration of beans).

В общем, проще всего поставить SpringBootApplication в корне вашего пакета иерархии (например, com.example.myapp), а затем расширить по мере необходимости (например, com.example.myapp.model). Если вы это сделаете, вам не нужно ничего делать, кроме аннотации вашего Application с SpringBootApplication для основного приложения. Возможно, вам понадобятся другие аннотации для дополнительных функций, таких как EnableJpaRepositories.

Если вы структурируете свой код, как предложено выше (поиск вашего класса приложения в корневом пакете), вы можете добавить @ComponentScan без каких-либо аргументов. Все ваши компоненты приложения (@Component, @Service, @Repository, @Controller и т. Д.) Будут автоматически зарегистрированы как Spring Beans.

«Автоматически зарегистрировано как« Весенние бобы »означает, что вам не нужно определять метод @Bean, который использует конструктор по умолчанию или Autwired. Они автоматически предоставляются для вас. Вам нужно только явно определить методы @Bean для вещей, которые вам нужно настроить вручную, например, что-то из пользовательского объекта Builder.

Смежные вопросы