Mam bardzo prostą aplikację Spring Boot, którą próbuję uruchomić z jakąś zewnętrzną konfiguracją. Próbowałem postępować zgodnie z informacjami zawartymi w dokumentacji bagażnika sprężynowego, ale napotykam blokadę drogową.
Kiedy uruchamiam aplikację poniżej, konfiguracja zewnętrzna w pliku application.properties nie jest umieszczana w zmiennej w komponencie bean. Jestem pewien, że robię coś głupiego, dzięki za wszelkie sugestie.
MyBean.java (znajduje się w / src / main / java / foo / bar /)
package foo.bar;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
public class MyBean {
@Value("${some.prop}")
private String prop;
public MyBean() {
System.out.println("================== " + prop + "================== ");
}
}
Application.java (znajduje się w / src / main / java / foo /)
package foo;
import foo.bar.MyBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
@Autowired
private MyBean myBean;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
application.properties (znajduje się w / src / main / resources /)
some.prop=aabbcc
Dane wyjściowe dziennika podczas wykonywania aplikacji Spring Boot:
grb-macbook-pro:properties-test-app grahamrb$ java -jar ./build/libs/properties-test-app-0.1.0.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.1.5.RELEASE)
2014-09-10 21:28:42.149 INFO 16554 --- [ main] foo.Application : Starting Application on grb-macbook-pro.local with PID 16554 (/Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app/build/libs/properties-test-app-0.1.0.jar started by grahamrb in /Users/grahamrb/Dropbox/dev-projects/spring-apps/properties-test-app)
2014-09-10 21:28:42.196 INFO 16554 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:42.828 INFO 16554 --- [ main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'beanNameViewResolver': replacing [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]] with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]]
2014-09-10 21:28:43.592 INFO 16554 --- [ main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-09-10 21:28:43.784 INFO 16554 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2014-09-10 21:28:43.785 INFO 16554 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.54
2014-09-10 21:28:43.889 INFO 16554 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2014-09-10 21:28:43.889 INFO 16554 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1695 ms
2014-09-10 21:28:44.391 INFO 16554 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2014-09-10 21:28:44.393 INFO 16554 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
================== null==================
2014-09-10 21:28:44.606 INFO 16554 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.679 INFO 16554 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.679 INFO 16554 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],methods=[],params=[],headers=[],consumes=[],produces=[text/html],custom=[]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2014-09-10 21:28:44.716 INFO 16554 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.716 INFO 16554 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2014-09-10 21:28:44.902 INFO 16554 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2014-09-10 21:28:44.963 INFO 16554 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080/http
2014-09-10 21:28:44.965 INFO 16554 --- [ main] foo.Application : Started Application in 3.316 seconds (JVM running for 3.822)
^C2014-09-10 21:28:54.223 INFO 16554 --- [ Thread-2] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@67e38ec8: startup date [Wed Sep 10 21:28:42 EST 2014]; root of context hierarchy
2014-09-10 21:28:54.225 INFO 16554 --- [ Thread-2] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
java
spring
spring-boot
grahamrb
źródło
źródło
@Value
go wymienić przed zbudowaniem fasoli? Twój sposób „wykrywania” nieprawidłowego ustawienia wartości. W tym momencie zawsze ma wartość zerową, ponieważ@Value
zostanie przetworzona PO budowie obiektu.Odpowiedzi:
Sposób wykonywania wstrzyknięcia właściwości nie będzie działał, ponieważ wstrzyknięcie jest wykonywane po wywołaniu konstruktora.
Musisz wykonać jedną z następujących czynności:
Lepsze rozwiązanie
@Component public class MyBean { private final String prop; @Autowired public MyBean(@Value("${some.prop}") String prop) { this.prop = prop; System.out.println("================== " + prop + "================== "); } }
Rozwiązanie, które będzie działać, ale jest mniej testowalne i nieco mniej czytelne
@Component public class MyBean { @Value("${some.prop}") private String prop; public MyBean() { } @PostConstruct public void init() { System.out.println("================== " + prop + "================== "); } }
Należy również pamiętać, że nie jest to specyficzne dla Spring Boot, ale dotyczy każdej aplikacji Spring
źródło
@ConfigurationProperties
i@EnableConfigurationProperties
adnotacjeUżytkownik „geoand” ma rację, wskazując przyczyny tego problemu i podając rozwiązanie. Ale lepszym podejściem jest hermetyzacja konfiguracji w oddzielnej klasie, powiedzmy klasy java SystemContiguration, a następnie wstrzyknięcie tej klasy do wszystkich usług, z których chcesz korzystać z tych pól.
Twój obecny sposób (@grahamrb) odczytywania wartości konfiguracyjnych bezpośrednio do usług jest podatny na błędy i spowodowałby refaktoryzację bólu głowy, jeśli nazwa ustawienia konfiguracji zostanie zmieniona.
źródło
Właściwie dla mnie poniżej działa dobrze.
@Component public class MyBean { public static String prop; @Value("${some.prop}") public void setProp(String prop) { this.prop= prop; } public MyBean() { } @PostConstruct public void init() { System.out.println("================== " + prop + "================== "); }
}
Teraz, gdziekolwiek chcę, po prostu przywołaj
MyBean.prop
zwróci wartość.
źródło
Ta odpowiedź może, ale nie musi, mieć zastosowanie w twoim przypadku ... Kiedyś miałem podobny objaw i wielokrotnie sprawdzałem mój kod wiele razy i wszystko wyglądało dobrze, ale
@Value
ustawienie nadal nie działało. A potem po zrobieniuFile > Invalidate Cache / Restart
z moimIntelliJ
(moim IDE) problem zniknął ...Jest to bardzo łatwe do wypróbowania, więc może warto spróbować
źródło
Korzystając z klasy Environment możemy pobrać aplikację. Wartości właściwości
@Autowired,
private Environment env;
i dostęp za pomocą
źródło
wykonaj następujące kroki. 1: - stwórz swoją klasę konfiguracji, jak widać poniżej
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.beans.factory.annotation.Value; @Configuration public class YourConfiguration{ // passing the key which you set in application.properties @Value("${some.pro}") private String somePro; // getting the value from that key which you set in application.properties @Bean public String getsomePro() { return somePro; } }
2: - jeśli masz klasę konfiguracyjną, wstrzyknij zmienną z konfiguracji, której potrzebujesz.
@Component public class YourService { @Autowired private String getsomePro; // now you have a value in getsomePro variable automatically. }
źródło
Jeśli pracujesz w dużym projekcie wielomodułowym z kilkoma różnymi
application.properties
plikami, spróbuj dodać swoją wartość do pliku właściwości projektu nadrzędnego .Jeśli nie masz pewności, który jest projektem nadrzędnym, sprawdź
pom.xml
plik projektu pod kątem rozszerzenia<parent>
tag.To rozwiązało problem.
źródło
Możesz użyć
Environment
Class, aby uzyskać dane:@Autowired private Environment env; String prop= env.getProperty('some.prop');
źródło