I am just getting started with Spring (Boot).
I have my "main" class in abc.de, annotated with #SpringApplication.
So far, everything works fine. I have only used stereotype annotations.
Now I would like to use #Bean with an #Configuration class, just to see how it works.
My #Configuration class:
#Configuration
public class BeanConfiguration {
#Bean
public XslDataFileLoader dataSource() {
return new XslDataFileLoader();
}
}
The class XslDataFileLoader is in the same package.
I declare this bean with #Autowired in a controller class.
So my "main" class is in abc.de, the config class is in abc.de.config and the XslDataFileLoader is in abc.de.config as well.
When I start the application, spring cannot inject the bean. It doesn't find it.
I tried scanPackages = abc.de.config: That way, none of my other beans are found.
How do I need to declare this in the latest spring boot?
EDIT
Stacktrace:
2017-05-19 13:52:03 ERROR o.s.b.d.LoggingFailureAnalysisReporter -
***************************
APPLICATION FAILED TO START
***************************
Description:
Field dataSource in abc.de.controllers.LoginController required a bean of type 'abc.de.config.XslDataFileLoader' that could not be found.
Action:
Consider defining a bean of type 'abc.de.config.XslDataFileLoader' in your configuration.
XslDataFileLoader:
package abc.de.config;
public class XslDataFileLoader {
public XslDataFileLoader() {
}
}
LoginController:
package abc.de.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import abc.de.config.XslDataFileLoader;
#Controller
public class LoginController {
#Autowired
XslDataFileLoader loader;
#GetMapping("/login")
public String login() {
System.out.println(loader);
return "login";
}
#PostMapping("/login")
public String loginTry() {
return "redirect:dashboard";
}
}
2ND EDIT
MySpringBootApplication:
package abc.de;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
#SpringBootApplication
#EnableJpaRepositories
public class MySpringBootApplication{
public static void main(final String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
application.properties:
server.port=5566
spring.application.name=#project.name#
# data source
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=
# Session
spring.session.store-type=none
# Security
security.basic.enabled=false
# logging
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n
logging.level.org.hibernate.SQL=debug
#logging.level.org.hibernate.type.descriptor.sql=trace
logging.level.=error
First, please post all of your code and the stacktrace.
The BeanConfiguration class is configured correctly so something is probably wrong with your injection.
Do you have annotations on XslDataFileLoader class? It might be a problem of double beans declaration and not bean not found (if you have both a #Component on XslDataFileLoader and at the same time declared it in BeanConfiguration)
Related
I'm trying to run the fallowing classes.
package com.example.demo;
import org.apache.catalina.core.ApplicationContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
#SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
var factory = new AnnotationConfigApplicationContext(AppConfig.class);
test tst = factory.getBean(test.class);
tst.getDummy().test();
SpringApplication.run(DemoApplication.class, args);
}
}
App config class:
package com.example.demo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
#Configuration
public class AppConfig {
#Bean
public test gettest(){
return new test();
}
//
#Bean
public test2 gettest2(){
return new test2();
}
}
First test class:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
#Component
public class test{
#Autowired
test2 dummy;
public void setDummy(test2 dummy) {
this.dummy = dummy;
}
public test2 getDummy() {
return dummy;
}
void test(){
System.out.println("test");
}
}
Second test class:
package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
#Component
public class test2{
public test2(){
}
void test(){
System.out.println("test2");
}
}
I get this error at run time
Field dummy in com.example.demo.test required a single bean, but 2 were found:
- test2: defined in file [/Users/biliuta/IdeaProjects/demo/build/classes/java/main/com/example/demo/test2.class]
- gettest2: defined by method 'gettest2' in class path resource [com/example/demo/AppConfig.class]
If i comment out the public test2 gettest2() bean from AppConfig I'll get this error:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'gettest': Unsatisfied dependency expressed through field 'dummy'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.test2' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
How come in the first case test2 bean is found and when I comment it out from AppConfig it is unable to find it anymore (in the first error message you can clearly see that test2 is found)? Is #Configure annotation mandatory to add beans to the context?
When you define #Component you define a bean which can be found for autowiring
When you define #Bean (in `#Configuration) you define a bean which can be found for autowiring
So you define twice same bean which caused spring to failed to know which one is the correct bean to autowire
Solution is to define only one time
how #Autowired works is it first try to find the required bean by type and a fallback mechanism is by bean name(ex: there are multiple beans for the same type)
but when you disable the #Bean annotation from AppConfig there should have been at least one bean of type Test2 as you have annotated Test2 with #Component annotation but it can't find it. To solve this you need to add #ComponentScan(basePackageClasses = { Test2.class }) on your AppConfig class as follows
#Configuration
#ComponentScan(basePackageClasses = { Test2.class })
public class AppConfig {
#Bean
public Test gettest(){
return new Test();
}
//#Bean
public Test2 gettest2(){
return new Test2();
}
}
but if you enable the bean annotation as follows
#Configuration
#ComponentScan(basePackageClasses = { Test2.class })
public class AppConfig {
#Bean
public Test gettest(){
return new Test();
}
#Bean
public Test2 gettest2(){
return new Test2();
}
}
you need to change the injection of Test2 on Test as by using
#Autowired
Test2 test2;
or by using
#Autowired
Test2 gettest2;
There are a few ways of making your class a bean in Spring / Spring Boot
Annotating your class with #Component or any other derived annotation(#Service, #Repository, #Controller, #RestController)
Defining your class as a bean in XML configuration
Using #Bean annotation(this one can be applied only to a method specify that it returns a bean to be managed by Spring context). #Bean annotation is usually declared in Configuration classes methods
When Spring initializes its context, it looks for any bean definitions and creates beans. In your case, it finds duplicate declarations of both test and test2, so you need either to remove your configuration class or remove the #Component annotations from your classes.
See Spring Bean documentation for more information
This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 3 years ago.
I am developing a spring boot application to send sms notification. This is my class for the purpose.
package org.otp.services;
import org.otp.Configurations;
import com.mashape.unirest.http.HttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
#Component
public class SmsService
{
private static final Logger LOG = LoggerFactory.getLogger(SmsService.class);
public String send(String mobile, String msg)
{
//Code
}
}
And this is the class which uses the above class for sending notification.
package org.otp.controllers;
import org.otp.Constants;
import org.otp.services.EmailService;
import org.otp.services.SmsService;
import org.otp.dto.MessageRequest;
import org.otp.dto.MessageResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
#Component
public class MessageController {
private static final Logger LOG = LoggerFactory.getLogger(MessageController.class);
#Autowired
SmsService smsService;
public void sendMessageToAlert(#RequestBody MessageRequest messageRequest)
{
String smsStatus = "FAIL";
MessageResponse messageResponse = new MessageResponse();
//1. Nullpointer
smsStatus = smsService.send(messageRequest.getMobileNo(),messageRequest.getMessage());
}
}
Main Class
package org.otp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
#SpringBootApplication
#EnableAsync
public class OtpServiceApplication implements ApplicationRunner
{
public static void main(String[] args) {
SpringApplication.run(OtpServiceApplication.class, args);
}
}
Problem is, I get a nullpointer exception in the (1) stating that my SmsService object is null. And my main class is in package org.otp so the two classes here falls under sub package so no need of component scan.
Therefore I am confused what to do to solve this. I have tried many answers here like adding a #Component annotation and #ComponentScan in main class but nothing works. Could someone please point out my mistake here.
Thanks in advance.
If your #Autowired annotation is not working and throws NPE ,it means that spring fails to create an instance of the component class in the application context . Try to:
Verify that the classes are in class path for scanning and also check to ensure that all auto-wired classes have the annotation #Component to enable them to be picked up during class path scanning.
Check the spring boot start up logs to verify if there are any errors
during bean creation.
Check to ensure all related classes used in the service layer are auto-wired properly and that the injected classes are annotated with #Component .
For further help please share the main application class along with your project structure.
Since you are using springboot , it is preferable to use the sprinboot stereotype annotations instead of the #Component annotation, if you are building a standard springboot web application.
#Service : for the service layer.
#Controller : for the controller layer . Also,DispatcherServlet will look for #RequestMapping on classes which are annotated using #Controller but not with #Component.
In Springboot application's main class add following annotation
#SpringBootApplication
#ComponentScan(
basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
public static void main(String[] args) {
SpringApplication.run(YourSpringMainClass.class, args);
}
}
While using annotations we should configured with #ComponentScan annotation to tell Spring the packages to scan for annotated components. This should be used in mail class(Which class wants to load first) in your case you are working with spring boot so you should use this annotation in Springboot application's main class. Like below
#SpringBootApplication
#ComponentScan(
basePackages = {"org.otp.*"}
)
public class YourSpringMainClass{
public static void main(String[] args) {
SpringApplication.run(YourSpringMainClass.class, args);
}
}
I am currently trying out a Spring boot application with Redis.I have a problem related to spring boot concerning redis repositories when I try to execute the program.
When I run the app I get the following error:
2017-09-02 09:21:37.065 INFO 5130 --- [st-startStop-18] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-09-02 09:21:37.106 WARN 5130 --- [st-startStop-18] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controller': Unsatisfied dependency expressed through method 'setSessionService' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sessionServiceImpl' defined in file [/rezsystem/apache-tomcat-8.0.36/webapps/sessionmanager/WEB-INF/classes/rezg/rezos/sessionmanager/services/SessionServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2017-09-02 09:21:37.118 INFO 5130 --- [st-startStop-18] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2017-09-02 09:21:37.306 ERROR 5130 --- [st-startStop-18] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
**Description:**
Parameter 0 of constructor in mezg.mezos.sessionmanager.services.SessionServiceImpl required a bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' that could not be found.
**Action:**
Consider defining a bean of type 'mezg.mezos.sessionmanager.repositories.SessionRepository' in your configuration.
The related source files are listed below
Service Interface
package mezg.mezos.sessionmanager.services;
import java.util.List;
public interface SessionService {
List<String> listAll();
String getById(String Key);
}
Service Implemention
package mezg.mezos.sessionmanager.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import mezg.mezos.sessionmanager.repositories.SessionRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
#Service
public class SessionServiceImpl implements SessionService{
private SessionRepository sessionRepository; //error refere to this
#Autowired
public SessionServiceImpl(SessionRepository sessionRepository) {
this.sessionRepository = sessionRepository;
}
#Override
public List<String> listAll() {
List<String> allSessions = new ArrayList<>();
sessionRepository.findAll().forEach(allSessions::add);
return allSessions;
}
#Override
public String getById(String Key) {
return sessionRepository.findOne(Key);
}
}
Repository
package mezg.mezos.sessionmanager.repositories;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
#Repository
public interface SessionRepository extends CrudRepository<String, String> {
}
Controller
package mezg.mezos.sessionmanager.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import mezg.mezos.sessionmanager.services.SessionService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.ui.Model;
#RestController
#RequestMapping(value="/sessionmanager")
public class SessionController {
final static Logger logger = LoggerFactory.getLogger(SessionController.class);
private SessionService sessionService;
#Autowired
public void setSessionService(SessionService sessionService) {
this.sessionService = sessionService;
}
#RequestMapping(value = "/servicecheck", method = RequestMethod.GET)
public String servicecheck() {
return "This is the First Message From Remote session manager service!";
}
#RequestMapping(value ="/all", method = RequestMethod.GET)
public String listAllSessions(Model model){
model.addAttribute("sessions", sessionService.listAll());
return "display all Sessions";
}
#RequestMapping("/session/show/{key}")
public String getProduct(#PathVariable String key, Model model){
model.addAttribute("product", sessionService.getById(key));
return "display selected Sessions";
}
}
Main class
package mezg.mezos.sessionmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan("mezg.mezos.sessionmanager")
public class SessionStoreApplication {
public static void main(String[] args) {
SpringApplication.run(SessionStoreApplication.class, args);
}
Gradle Dependencies
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-redis')
compile('org.springframework.boot:spring-boot-starter-web')
providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
There were similar scenarios described on this forum and I did try out the suggested solutions but could resolve this issue.Some of these issue are listed below.
Stack overflow Reference
Consider defining a bean of type 'com.ensat.services.ProductService' in your configuration
Consider defining a bean of type 'package' in your configuration [Spring-Boot]
Consider defining a bean of type 'service' in your configuration [Spring boot]
Spring boot CrudRepo Define a bean
Spring boot + redis
Other References
http://www.cnblogs.com/exmyth/p/7119225.html
------------------------UPDATE 1-----------------------
Tried Updating the Main Class with #ComponentScan and #EnableRedisRepositories
package mezg.mezos.sessionmanager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
#SpringBootApplication
#EnableAutoConfiguration
#ComponentScan({"mezg.mezos.sessionmanager","mezg.mezos.sessionmanager.controller","mezg.mezos.sessionmanager.services","mezg.mezos.sessionmanager.repositories"})
#EnableRedisRepositories("mezg.mezos.sessionmanager.repositories")
public class SessionStoreApplication {
public static void main(String[] args) {
SpringApplication.run(SessionStoreApplication.class, args);
}
}
------------------------UPDATE 2-----------------------
Full Logs
https://gist.github.com/lrrp/3065dff578daa92dacf4bdc78f90c9b5
Any suggestion on how how I can fix this Spring boot error and any best practices to follow in situations such as this?
I'm building JPA configuration with multiple persistence units using different in-memory datasources, but the configuration fails resolving the qualified datasource for entity manager factory bean with the following error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method emfb in datasources.Application$PersistenceConfiguration required a single bean, but 2 were found:
- ds1: defined by method 'ds1' in class path resource [datasources/Application$PersistenceConfiguration.class]
- ds2: defined by method 'ds2' in class path resource [datasources/Application$PersistenceConfiguration.class]
Action:
Consider marking one of the beans as #Primary, updating the consumer to accept multiple beans, or using #Qualifier to identify the bean that should be consumed
Here is the sample application
package datasources;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.sql.DataSource;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.apache.log4j.Logger;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.stereotype.Component;
#Configuration
#EnableAutoConfiguration(exclude = {
// HibernateJpaAutoConfiguration.class,
// DataSourceAutoConfiguration.class
JtaAutoConfiguration.class
})
#ComponentScan
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.build()
.run(args);
}
#Component
#Path("/ds")
public static class DsApi {
private final static Logger logger = Logger.getLogger(DsApi.class);
#Autowired(required = false)
#Qualifier("ds1")
private DataSource ds;
#GET
public String ds() {
logger.info("ds");
return ds.toString();
}
}
#Component
#Path("/em")
public static class EmApi {
private final static Logger logger = Logger.getLogger(EmApi.class);
#PersistenceContext(unitName = "ds2", type = PersistenceContextType.TRANSACTION)
private EntityManager em;
#GET
public String em() {
logger.info("em");
return em.toString();
}
}
#Configuration
#ApplicationPath("/jersey")
public static class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(DsApi.class);
register(EmApi.class);
}
}
#Configuration
public static class PersistenceConfiguration {
#Bean
#Qualifier("ds1")
public DataSource ds1() {
return new EmbeddedDatabaseBuilder().build();
}
#Bean
#Qualifier("ds2")
public DataSource ds2() {
return new EmbeddedDatabaseBuilder().build();
}
#Bean
#Primary
#Autowired
public LocalContainerEntityManagerFactoryBean emfb(#Qualifier("ds1") DataSource ds, EntityManagerFactoryBuilder emfb) {
return emfb.dataSource(ds)
.packages(Application.class)
.persistenceUnit("ds1")
.build();
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean emfb2(#Qualifier("ds2") DataSource ds, EntityManagerFactoryBuilder emfb) {
return emfb.dataSource(ds)
.packages(Application.class)
.persistenceUnit("ds2")
.build();
}
}
}
The error is indicating that at some point in the application, a bean is being injected by the type DataSource and not being qualified by name at that point.
It does not matter that you have added #Qualifier in one location. The injection is failing in some other location that has not been qualified. It's not your fault though because that location is in Spring Boot's DataSourceAutoConfiguration which you should be able to see in your stack trace, below the piece that you have posted.
I would recommend excluding DataSourceAutoConfiguration i.e. #SpringBootApplication(exclude = DataSourceAutoConfiguration.class). Otherwise, this configuration is only being applied to the bean you have made #Primary. Unless you know exactly what that is, it is likely to result in subtle and unexpected differences in behaviour between your DataSources.
Declare one of your DataSource as #Primary.
Also you have 2 beans of same type - LocalContainerEntityManagerFactoryBean, declare one of them #Primary as well, as follows:
#Configuration
public static class PersistenceConfiguration {
#Bean
#Primary
public DataSource ds1() {
return new EmbeddedDatabaseBuilder().build();
}
#Bean
public DataSource ds2() {
return new EmbeddedDatabaseBuilder().build();
}
#Bean
#Primary
#Autowired
public LocalContainerEntityManagerFactoryBean emfb(#Qualifier("ds1") DataSource ds, EntityManagerFactoryBuilder emfb) {
return emfb.dataSource(ds)
.packages(DemoApplication.class)
.persistenceUnit("ds1")
.build();
}
#Bean
#Autowired
public LocalContainerEntityManagerFactoryBean emfb2(#Qualifier("ds2") DataSource ds, EntityManagerFactoryBuilder emfb) {
return emfb.dataSource(ds)
.packages(DemoApplication.class)
.persistenceUnit("ds2")
.build();
}
}
Try declaring the datasource beans outside the static class . I.e directly in Application.java
I am having an issue since I moved to version 1.1.4.RELEASE of Spring Boot.
My variables that are annotated with #Value are presently not being populated with values despite them being present in the application.properties. Prior to this I was using Spring Boot # version 1.0.2, and that was working fine.
It all started since the upgrade, and I made no code change.
SampleApplication.java
package org.sample;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
#Configuration
#ComponentScan
#EnableAutoConfiguration
#PropertySource(value = "classpath:application.properties")
public class SampleApplication {
private static Logger logger = LoggerFactory
.getLogger(TaskManagerApplication.class);
#Value("${org.sample.sampleProperty}")
private static String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
System.out.print("SampleApplication started: " + sampleProperty);
}
#Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
application.properties
spring.datasource.url: jdbc:mysql://127.0.0.1:3306/mydb
spring.datasource.username: root
spring.datasource.password: root
spring.datasource.driverClassName: com.mysql.jdbc.Driver
spring.jpa.show-sql: true
#Disable the ddl-auto:create once tables have been created
#spring.jpa.hibernate.ddl-auto: create
org.sample.sampleProperty=This is a sample property
photos.upload.dir=C:/temp/UserPhotos/
# Server port
server.port=8081
I have tried to add a PropertySourcesPlaceholderConfigurer bean and even PropertySourcesPlaceholderConfigurer but still the issue persists.
Anyone experienced this ? Or is there a new way to load the properties file ?
Please note that my db connection and server port are being read properly since my application can connect to db and I have to access it through the specified port.
sampleProperty variable remains null though.
#Value is not meant to work on static fields
Properties from application.properties are available automatically without specifying #PropertySource for it.
Instead of printing out property in main() method, you should do it after bean is constructed, for example by using #PostConstruct
Fully working example:
package demo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class Application {
#Value("${org.sample.sampleProperty}")
private String sampleProperty;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#PostConstruct
public void postConstruct() {
System.out.print("SampleApplication started: " + sampleProperty);
}
}