Michael Knight
Michael Knight

Reputation: 648

Reading application.properties from any class in spring boot

When I add a property in the application.properties files, this can be access from the main class without any problem.

    @SpringBootApplication
    @ComponentScan(basePackages = "com.example.*")
    public class MailTestApplication implements CommandLineRunner {

        @Value("${admin.mail}")
        String email;

        public static void main(String[] args) {
            SpringApplication.run(MailTestApplication.class, args);
        }

        @Override
        public void run(String... strings) throws Exception {

            System.out.println(email);
            Email email = new Email();
            email.sendMail();
        }
    }

However, when I try to access it from any other class it is never retrieved.

    @Component
    public class Email {

        @Autowired
        private MailSender sender;

        @Value("${admin.mail}")
        String email;

        public Email() {
        }

        public void sendMail() {
            SimpleMailMessage msg = new SimpleMailMessage();

            System.out.println(email);

            msg.setTo("[email protected]");
            msg.setSubject("Send mail by Spring Boot");
            msg.setText("Send mail by Spring Boot");

            sender.send(msg);
        }
    }

I was reading some of the previous questions other users posted without a clear result for me. I even tried to find some examples with similar resutl.

Could someone give me any clue about this?

Thanks a lot in advance.

Upvotes: 2

Views: 3060

Answers (1)

jstuartmilne
jstuartmilne

Reputation: 4488

The @Value should work (Im asuming your class is under the com.example.* package since you are scanning that package) but if you want to do it another way this is what im using :

public class JpaConfiguration {

    public static final String TRANSACTION_MANAGER_NAME = "jpaTransactionManager";

    @Autowired
    Environment applicationProperties;

Then to use it

@Bean
    public DriverManagerDataSource driverManagerDataSource() {
        DriverManagerDataSource driverConfig = new DriverManagerDataSource();

        driverConfig.setDriverClassName(applicationProperties.getProperty("data.jpa.driverClass"));
        driverConfig.setUrl(applicationProperties
                .getProperty("data.jpa.connection.url"));
        driverConfig.setUsername(applicationProperties
                .getProperty("data.jpa.username"));
        driverConfig.setPassword(applicationProperties
                .getProperty("data.jpa.password"));

        return driverConfig;
    }

UPDATE AFTER GETTING THE GITHUB REPO

I Don't really know what you are trying to build but :

If you do this:

@Override
    public void run(String... strings) throws Exception {

        //System.out.println(email);
        Email email = new Email();
        email.sendMail();
    }

Then you are creating the instance of the class, and not spring. so you shouldn't be creating the instance yourself there it should be spring. That said, i dont know if you are creating a web application a command line application or both.

That said ill give you a minor solution to show you that the dependency injection is in fact working.

1_ add a getter to your email on email class. remove the CommandLine interface (If you want to implement this i would recomend you to put CommandLine implmentations on another package say Controller);

And then run your app like this:

@SpringBootApplication
@ComponentScan(basePackages = "com.example")
public class MailTestApplication  {

    @Value("${admin.mail}")
    String email;

    public static void main(String[] args) {
       // SpringApplication.run(MailTestApplication.class, args);

        final ConfigurableApplicationContext context = new SpringApplicationBuilder(MailTestApplication.class).run(args);

        Email e = context.getBean(Email.class);
        System.out.println(e.getEmail());
    }

The Key thing I want to show is that the instance is created by spring thats why the wiring works. and the email gets printed in the console. Regarding the email class :

@Component
public class Email {

//    @Autowired
  //  private MailSender sender;

    @Value("${admin.mail}")
    String email;

    public Email() {
    }

    public void sendMail() {
        SimpleMailMessage msg = new SimpleMailMessage();

        System.out.println(email);

        msg.setTo("[email protected]");
        msg.setSubject("Send mail by Spring Boot");
        msg.setText("Send mail by Spring Boot");

       // sender.send(msg);
    }

    public String getEmail() {
        return email;
    }


}

I Comment out the MailSender since I think you need to configure that too, i have made a custom mailSender that uses gmail and other for mailChimp that i can share with you if you need. but again I dont really know what your intent with the app is.

Hope the info helps you.

Upvotes: 1

Related Questions