【问题标题】:Reading application.properties from any class in spring boot从 Spring Boot 中的任何类中读取 application.properties
【发布时间】:2015-12-20 11:01:10
【问题描述】:

当我在 application.properties 文件中添加一个属性时,可以从主类毫无问题地访问它。

    @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();
        }
    }

但是,当我尝试从任何其他类访问它时,它永远不会被检索到。

    @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("sample@email.com");
            msg.setSubject("Send mail by Spring Boot");
            msg.setText("Send mail by Spring Boot");

            sender.send(msg);
        }
    }

我正在阅读其他用户之前发布的一些问题,但对我没有明确的结果。我什至试图找到一些结果相似的例子。

有人可以给我任何线索吗?

非常感谢。

【问题讨论】:

  • 如果您发现任何错误。在此处粘贴堆栈跟踪。
  • 属性读取完全没有错误。问题是当我尝试从任何非主类中读取该值时,该值始终为空。
  • 我对弹簧靴不熟悉。我怀疑这可能是范围或依赖性的问题。我建议您在主类中获取该属性,存储在成员变量中,创建 getter 和 setter,并尝试通过注入主类实例从其他类访问变量的 getter 方法。这种方法会更好,因为您不会重复访问属性文件。
  • 这可能是一种解决方法,但不是解决方案本身。我宁愿知道它是如何工作的,以更好地理解框架。
  • 这并不能直接回答您的问题,但我一直倾向于将 Environment 注入我的组件并从中读取属性。我觉得它更干净一些。

标签: properties spring-boot


【解决方案1】:

@Value 应该可以工作(我假设您的课程在 com.example.* 包下,因为您正在扫描该包)但是如果您想以另一种方式进行操作,这就是我正在使用的:

public class JpaConfiguration {

    public static final String TRANSACTION_MANAGER_NAME = "jpaTransactionManager";

    @Autowired
    Environment applicationProperties;

然后使用它

@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;
    }

获取 GITHUB 存储库后更新

我真的不知道您要构建什么,但是:

如果你这样做:

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

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

那么你是在创建类的实例,而不是 spring。所以你不应该在那里自己创建实例,它应该是春天。 也就是说,我不知道您是在创建 Web 应用程序还是命令行应用程序或两者兼而有之。

这就是说我给你一个小解决方案来告诉你依赖注入实际上是有效的。

1_ 在电子邮件类的电子邮件中添加一个吸气剂。删除 CommandLine 接口(如果你想实现这个,我建议你将 CommandLine 实现放在另一个包上,比如 Controller);

然后像这样运行您的应用程序:

@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());
    }

我想展示的关键是实例是由 spring 创建的,这就是接线工作的原因。并且电子邮件在控制台中打印。 关于电子邮件类:

@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("sample@email.com");
        msg.setSubject("Send mail by Spring Boot");
        msg.setText("Send mail by Spring Boot");

       // sender.send(msg);
    }

    public String getEmail() {
        return email;
    }


}

我注释掉 MailSender,因为我认为您也需要配置它,我制作了一个自定义 mailSender,它使用 gmail 和其他用于 mailChimp 的邮件,如果您需要,我可以与您共享。但同样我真的不知道你对应用程序的意图是什么。

希望这些信息对您有所帮助。

【讨论】:

  • 感谢@Sudakatux 的回答。就我而言,两者都在同一个包中,但仍然无法正常工作。如果它们在不同的包中,我想添加 ComponentScan(basePackages = "com.example.*") 如果我首先让它在同一个包中工作就足够了。
  • 好的,但是您的 mailSenderService 实际上正在被注入,对吗?
  • 没有! MailSender 也是空的。我想是因为同样的原因。
  • 好的,你的 MailSender(假设是定制的)应该在包 com.example.{somechild} 中,并且这个类也应该在那个包或子包中,否则 spring 不会用它们创建实例。如果您想扫描多个包裹,您可以这样做@ComponentScan(basePackages={"com.asimplemodule.controller", "com.asimplemodule.config", "com.asimplemodule.security"})希望对您有所帮助
  • 是的,所有类都在同一个包中,以避免任何设置问题。
猜你喜欢
  • 2018-01-07
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2020-06-29
  • 1970-01-01
  • 2020-07-08
相关资源
最近更新 更多