@Value不能从application.properties插入数据

时间:2018-08-16 15:55:29

标签: java spring model-view-controller

我将向您展示一些代码,然后问一个问题。

SendEmail.java

package com.goode;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

@Component
@NoArgsConstructor
@Data
@AllArgsConstructor
public class SendEmail {

  @Value("${email.username}")
  private String username;

  @Value("${email.password}")
  private String password;

  @Value("${email.fullAddress}")
  private String fullAddress;

  @Value("${email.host}")
  private String host;

  @Value("${email.port}")
  private String port;

  public boolean send(String toEmail, String subject, String message){
    Properties props = new Properties();
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.starttls.enable", "true");
    props.put("mail.smtp.host", host);
    props.put("mail.smtp.port", port);

    Session session = Session.getInstance(props,
        new javax.mail.Authenticator() {
          protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
          }
        });

    try {
      Message createMessage = new MimeMessage(session);
      createMessage.setFrom(new InternetAddress(fullAddress));
      createMessage.setRecipients(Message.RecipientType.TO,
          InternetAddress.parse(toEmail));
      createMessage.setSubject(subject);
      createMessage.setText(message);
      Transport.send(createMessage);

      return true;

    } catch (MessagingException e) {
      throw new RuntimeException(e);
    }
  }

  @Bean
  public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
  {
    PropertySourcesPlaceholderConfigurer o = new PropertySourcesPlaceholderConfigurer();
    o.setLocation(new ClassPathResource("application.properties"));
    return o;
  }
}

RootConfig.java

package com.goode.config;

import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableJpaRepositories( basePackages = {"com.goode.repository"})
@PropertySource(value = { "classpath:application.properties" })
@EnableTransactionManagement
@Import({ SecurityConfig.class })
@ComponentScan(basePackages = {"com.goode.service", "com.goode.repository", "com.goode.controller", "com.goode.business", "com.goode"})
public class RootConfig {

  @Autowired
  private Environment environment;

  @Autowired
  private DataSource dataSource;

  @Bean
  public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
    dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
    dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
    dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));

    return dataSource;
  }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
    vendorAdapter.setDatabase(Database.POSTGRESQL);
    vendorAdapter.setGenerateDdl(true);
    vendorAdapter.setShowSql(true);

    LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
    factory.setJpaVendorAdapter(vendorAdapter);
    factory.setPackagesToScan("com.goode.business");
    factory.setDataSource(dataSource());
    factory.setJpaProperties(jpaProperties());

    return factory;
  }

  private Properties jpaProperties() {
    Properties properties = new Properties();
    properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
    properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
    return properties;
  }
  @Bean
  public PlatformTransactionManager transactionManager() {

    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return txManager;
  }

}

application.properties

jdbc.driverClassName = org.postgresql.Driver
jdbc.url = jdbc:postgresql://localhost:5432/GoodE
jdbc.username = postgres
jdbc.password = postgres
hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
hibernate.show_sql = true
hibernate.format_sql = true
email.username = xx //I replce real data to xx just to this post
email.password = xx
email.fullAddress = xx@xx.com
email.host = xx
email.port = xx

当我尝试从SendEmail控制台调用发送方法时显示错误:

  

java.lang.NullPointerException:空

所在行:

  

props.put(“ mail.smtp.host”,主机);

因此,注释@Value不会将application.properties中的任何值注入到SendEmail中的私有变量中。为什么会这样?

RootConfig.java 中,我使用了 @Autowired Environment @PropertySource ,但我在某处读到了只能在@Configuration类中使用@PropertySource,所以我试图找到另一种方法->我发现了@Value,但是我不知道为什么application.properties中的数据没有注入变量。 我将 PropertySourcesPlaceholderConfigurer 放在SendEmail中,因为我读到它是必需的。我不确定这是正确的地方,但是将其放置在另一个类中RootConfig没有帮助。 您可能有什么建议我应该在哪里搜索错误?

1 个答案:

答案 0 :(得分:1)

此行: import requests r= requests.get("https://www.bing.com") print (r.status_code) 这是不必要的,因为默认情况下会选取@PropertySource(value = { "classpath:application.properties" })中的所有值。话虽如此,您也不需要application.properties

请确保在调用您的PropertySourcesPlaceholderConfigurer方法时,不要将send类实例化为SendEmail,因为它不能像new SendEmail()那样仅在内部运行。春天的应用程序上下文。

您必须进行@Value或构造函数注入(建议使用后者)。

这也是: @Autowired 可以替换为: @ComponentScan(basePackages = {"com.goode.service", "com.goode.repository", "com.goode.controller", "com.goode.business", "com.goode"})