2017-07-08 6 views
1

Mein Beispielprojekt ist Maven-basierte Struktur, alle meine Anwendungsprojekten Dateien unter src/main/resources Ordner. Unten ist der vollständige Beispielcode. Ich verstehe nicht, warum mein Code nicht in der Lage ist, Profile richtig zu finden, wenn ich @PropertySource Annotation nicht verwende.Spring Profiles org.springframework.beans.factory.NoSuchBeanDefinitionException

Meine eigentliche Zweifel ist: Ich habe Spring-Eigenschaften ziemlich gut in application.properties Datei konfiguriert, aber warum kann es nicht finden, Profil und ihre jeweiligen Eigenschaft Dateien? Es sei denn, ich verwende @PropertySource Annotation, IAM nicht Wert für env.getProperty ("mysql.url") erhalten. Ich meine Environment Klasse nicht in der Lage, Werte von Profilen Eigenschaft Dateien abholen. WARUM?

Iam immer Fehler wie folgt:

Jul 08, 2017 7:54:26 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 
INFO: Refreshing org.spring[email protected]300ffa5d: startup date [Sat Jul 08 19:54:26 IST 2017]; root of context hierarchy 
helloBean 
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'datasource' available 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1084) 
    at com.oreilly.datasource.Main2.main(Main2.java:15) 

DatasourceConfig.java

package com.oreilly.datasource; 

import javax.sql.DataSource; 

import org.apache.commons.dbcp.BasicDataSource; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Profile; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.context.annotation.PropertySources; 
import org.springframework.core.env.Environment; 

@Configuration 
/*@PropertySource("classpath:/application.properties") 
@PropertySource("classpath:/dev/application-dev.properties") 
@PropertySource("classpath:/prod/application-prod.properties")*/ 
public class DatasourceConfig { 

    @Autowired 
    private Environment env; 

    @Bean(name="helloBean") 
    public String helloWorld() { 
     System.out.println("helloBean"); 
     return "helloWorld...."; 
    } 

    @Bean(name="datasource") 
    @Profile("dev") 
    public DataSource datasourceForDev(){ 
     BasicDataSource dataSource = new BasicDataSource(); 
     System.out.println(env.getProperty("mysql.url")); 
     return dataSource; 
    } 

    @Bean(name="datasource") 
    @Profile("prod") 
    public DataSource datasourceForProd(){ 
     BasicDataSource dataSource = new BasicDataSource(); 
     System.out.println(env.getProperty("mysql.url")); 
     return dataSource; 
    } 
} 

Main2.java

package com.oreilly.datasource; 

import javax.sql.DataSource; 

import org.apache.commons.dbcp.BasicDataSource; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.context.annotation.AnnotationConfigApplicationContext; 

public class Main2 { 


    public static void main(String[] args) { 
     AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DatasourceConfig.class); 

     DataSource dataSource = context.getBean("datasource", DataSource.class); 
     String helloBean = context.getBean("helloBean", String.class); 


    } 

} 

application.properties

spring.profiles.active=prod 
spring.config.name=application 
spring.config.location=classpath:/application.properties,classpath:/dev/application-dev.properties,classpath:/prod/application-dev.properties 

Unten ist die Ordnerstruktur Projekt:

enter image description here

Bitte sagen Sie mir, was falsch gelaufen?

Antwort

0

Ich habe mein Problem nur gelöst, wie unten durch Modifizieren:

@PropertySource("classpath:/${spring.profiles.active}/application-${spring.profiles.active}.properties") 

nun zur Abholung application-dev.properties Ich bin in der Lage (oder) dynamisch application-prod.properties.

Hinweis: Environment Klasse erfordert @PropertySource Anmerkung, sonst bekommen wir für env.get ('someproperty') null.

0
@Configuration 
@PropertySource("classpath:application.properties") 
public class DatasourceConfig { 
.... 
} 

Put-Property-Datei in derselben Lage wie application.property und folgen der Namenskonvention anwendungs- {Profil} .properties wie application-dev.properties, application-prod.properties.


‚Ich möchte Properties-Datei auf Profil automatisch basierend abgeholt werden ich in application.properties erklärt.‘ :

Führen Sie Ihre Anwendung mit -Dspring.profiles.active = dev/prod. Spring load 1) application.property, 2) pplication-dev/prod.properties Datei mit Overides Wert aus application.property

+0

Ich möchte Eigenschaftendatei automatisch basierend auf Profil, das ich in application.properties deklariert. – John

+0

Ohne Verwendung von @PropertySource sollte funktionieren, wie? Ich meine es sollte meine application-dev.properties automatisch abholen, wie? – John

1

Der Frühling ist schlau, es wählt die application-x.properties (wobei x die Umgebung ist) abhängig von Der Wert, der in den application.properties der Eigenschaft spring.profiles.active zugewiesen ist, sodass Sie sich keine Gedanken darüber machen müssen, alle Dateien in verschiedenen @PropertySource-Annotationen zu registrieren.

Sie können hier weitere Informationen erhalten: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

Ich schlage vor, Sie alle @Profile Anmerkungen entfernen und nur eine Datenquelle lassen, die variabel sein wird (je nach angewählter Umgebung von application.properties). Sie können dies mit dem Beispiel verstehen, dass ich am Ende dieses Beitrags gestellt habe.

Wenn Sie eine mysql.url für ein bestimmtes Profil definieren möchten (z. B. dev), müssen Sie die Datei "mysql.url" in der Datei application-dev.properties hinzufügen und dann die Komponente spring.profiles festlegen. aktiver Wert für dev in application.properties.

Dann in Ihrem DatasourceConfig.java, können Sie so etwas wie dies ausführen:

@Autowired 
private Environment env; 

//Takes the mysqlUrl from application-x.properties (where x is the value of spring.profiles.active that comes from application.properties) 
@Value("${mysql.url}") 
private String mysqlUrl; 

@Bean(name="helloBean")... 

@Bean(name="datasource") 
public DataSource datasource() { 
    BasicDataSource dataSource = new BasicDataSource(); 
    System.out.println(mySqlUrl); //This value is variable depending of the profile that you're pointing on. 
    return dataSource; 
} 

Bitte lassen Sie mich wissen, dass es das für Sie nützlich ist.

+0

Ein zusätzlicher Kommentar: Sie müssen Ihre Dateien application.properties und application-x.properties im Ressourcenstamm definieren, damit Spring sie automatisch erkennt. –

+0

Ich denke, dass Sie meine Abfrage richtig verstehen sollten. Wir sollten die Environment-Klasse verwenden anstatt jede Eigenschaftsvariable wie "mysql.url" zu deklarieren ... Ich habe @Profile-Annotation mit 2 Methoden deklariert, um 2 Profile (dev und prod) zu deklarieren. . – John

Verwandte Themen