J'ai une application Spring-Boot en tant que projet multimodule dans maven. La structure est la suivante:
Parent-Project
|--MainApplication
|--Module1
|--ModuleN
Dans le projet MainApplication
, il y a la classe de méthode main()
annotée avec @SpringBootApplication
et ainsi de suite. Comme toujours, ce projet a un fichier application.properties qui est chargé automatiquement. Je peux donc accéder aux valeurs avec l'annotation @Value
@Value("${myapp.api-key}")
private String apiKey;
Dans mon Module1, je souhaite également utiliser un fichier de propriétés (appelé module1.properties), dans lequel la configuration des modules est stockée. Ce fichier sera uniquement utilisé et utilisé dans le module. Mais je ne peux pas le charger. Je l'ai essayé avec @Configuration
et @PropertySource
mais pas de chance.
@Configuration
@PropertySource(value = "classpath:module1.properties")
public class ConfigClass {
Comment puis-je charger un fichier de propriétés avec Spring-Boot et accéder facilement aux valeurs? Impossible de trouver une solution valide.
Ma configuration
@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {
@Value("${moviedb.tmdb.api-key}")
private String apiKey;
public String getApiKey() {
return apiKey;
}
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Appel de la configuration
@Component
public class TMDbWarper {
@Autowired
private TMDbConfig tmdbConfig;
private TmdbApi tmdbApi;
public TMDbWarper(){
tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}
Je reçois une exception NullPointerException dans le constructeur lorsque je câble automatiquement le warper.
Pour l'injection sur le terrain:
Les champs sont injectés juste après la construction d'un bean, avant que des méthodes de configuration ne soient appelées. Un tel champ de configuration ne doit pas nécessairement être public. Référez-vous Annotation auto-câblée pour une utilisation complète. Utilisez l'injection de constructeur dans ce cas comme ci-dessous:
@Component
public class TMDbWarper {
private TMDbConfig tmdbConfig;
private TmdbApi tmdbApi;
@Autowired
public TMDbWarper(final TMDbConfig tmdbConfig){
this.tmdbConfig = tmdbConfig;
tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}
(ou)
Utilisez @PostConstruct
pour initialiser comme ci-dessous:
@Component
public class TMDbWarper {
@Autowired
private TMDbConfig tmdbConfig;
private TmdbApi tmdbApi;
@PostConstruct
public void init() {
// any initialisation method
tmdbConfig.getConfig();
}
Le câblage automatique est effectué juste après la création de l'objet (après avoir appelé le constructeur par réflexion). Donc, NullPointerException
est attendu dans votre constructeur car le champ tmdbConfig
serait nul lors de l'appel du constructeur
Vous pouvez résoudre ce problème en utilisant la méthode de rappel @PostConstruct comme indiqué ci-dessous:
@Component
public class TMDbWarper {
@Autowired
private TMDbConfig tmdbConfig;
private TmdbApi tmdbApi;
public TMDbWarper() {
}
@PostConstruct
public void init() {
tmdbApi = new TmdbApi(tmdbConfig.getApiKey());
}
public TmdbApi getTmdbApi() {
return this.tmdbApi;
}
}
Le reste de votre configuration me semble correct.
J'espère que cela t'aides.
Voici un exemple de multi-module Spring Boot où vous pouvez obtenir des propriétés dans différents modules . Disons que j'ai main application module, dataparse-module , datasave-module.
StartApp.Java dans application module:
@SpringBootApplication
public class StartApp {
public static void main(String[] args) {
SpringApplication.run(StartApp.class, args);
}
}
Configuration dans dataparse-module . ParseConfig.Java:
@Configuration
public class ParseConfig {
@Bean
public XmlParseService xmlParseService() {
return new XmlParseService();
}
}
XmlParseService.Java:
@Service
public class XmlParseService {...}
Configuration dans datasave-module . SaveConfig.Java:
@Configuration
@EnableConfigurationProperties(ServiceProperties.class)
@Import(ParseConfig.class)//get beans from dataparse-module - in this case XmlParseService
public class SaveConfig {
@Bean
public SaveXmlService saveXmlService() {
return new SaveXmlService();
}
}
ServiceProperties.Java:
@ConfigurationProperties("datasave")
public class ServiceProperties {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
application.properties dans le dossier datasave-module in resource/config:
datasave.message = Projet Maven multi-module!
threads.xml.number = 5
file.location.on.disk = D:\temp\registry
Ensuite, dans datasave-module , vous pouvez utiliser toutes vos propriétés via @Value.
SaveXmlService.Java:
@Service
public class SaveXmlService {
@Autowired
XmlParseService xmlParseService;
@Value("${file.location.on.disk: none}")
private String fileLocation;
@Value("${threads.xml.number: 3}")
private int numberOfXmlThreads;
...
}
Ou via ServiceProperties:
Service.Java:
@Component
public class Service {
@Autowired
ServiceProperties serviceProperties;
public String message() {
return serviceProperties.getMessage();
}
}
J'ai eu cette situation auparavant, j'ai remarqué que le fichier de propriétés n'a pas été copié dans le pot.
J'ai fait le suivant pour le faire fonctionner:
Dans le dossier des ressources, j'ai créé un package unique, puis stocké mon fichier application.properties à l'intérieur de celui-ci. par exemple: com/société/projet
Dans le fichier de configuration, par exemple: TMDBConfig.Java, j'ai référencé le chemin complet de mon fichier .properties:
@Configuration
@PropertySource("classpath:/com/company/project/application.properties")
public class AwsConfig
Construire et exécuter, cela fonctionnera comme par magie.
Vous pouvez autowire et utiliser le Enviornment
bean pour lire la propriété
@Configuration
@PropertySource(value = "classpath:tmdb.properties")
public class TMDbConfig {
@Autowired
private Environment env;
public String getApiKey() {
return env.getRequiredProperty("moviedb.tmdb.api-key");
}
}
Cela devrait garantir que la propriété est lue à partir du contexte lorsque vous appelez la méthode getApiKey()
, que la résolution de @Value
soit résolue par PropertySourcesPlaceholderConfigurer
.