[英]@Value not inject data from application.properties
I will show you a little code and then I will ask a question. 我将向您展示一些代码,然后问一个问题。
SendEmail.java 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 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 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
When I try call a send method from SendEmail console shows error: 当我尝试从SendEmail控制台调用send方法时,显示错误:
java.lang.NullPointerException: null
java.lang.NullPointerException:空
in line: 排队:
props.put("mail.smtp.host", host);
props.put(“ mail.smtp.host”,host);
So annotation @Value doesn't inject any value from application.properties to private variable in SendEmail. 因此,批注@Value不会将application.properties中的任何值注入到SendEmail中的私有变量中。 Why is that?
这是为什么?
In RootConfig.java I used @Autowired , Environment and @PropertySource but I read somewhere that you can use @PropertySource only in @Configuration class so I tried find another way -> I found @Value, but I have no idea why data from application.properties are not injecting to variable. 在RootConfig.java中,我使用了@ Autowired , Environment和@PropertySource,但是我读到某个地方只能在@Configuration类中使用@PropertySource,所以我尝试找到另一种方式->我找到了@Value,但是我不知道为什么来自应用程序的数据.properties不会注入变量。 I put PropertySourcesPlaceholderConfigurer in SendEmail because I read it's necessary.
我将PropertySourcesPlaceholderConfigurer放在SendEmail中,因为我读到它是必需的。 I am not sure this is the right place for it but placing this in another class eg RootConfig didn't help.
我不确定这是否合适,但是将其放在另一个类(例如RootConfig)中并没有帮助。 May you have any advice where should I search for bug?
您可能有什么建议我应该在哪里搜索错误?
This line: @PropertySource(value = { "classpath:application.properties" })
is unnecessary because all values from application.properties
are picked up by default. 此行:
@PropertySource(value = { "classpath:application.properties" })
是不必要的,因为默认情况下会拾取来自application.properties
所有值。 That being said, you also don't need PropertySourcesPlaceholderConfigurer
for that. 话虽如此,您也不需要
PropertySourcesPlaceholderConfigurer
。
Make sure that when calling your send
method, that you are not instantiating your SendEmail
class as new SendEmail()
because that will not work as @Value
works only inside of the spring application context. 请确保在调用
send
方法时,不要将您的SendEmail
类实例化为new SendEmail()
因为它将不起作用,因为@Value
仅在spring应用程序上下文内部有效。
You must either do an @Autowired
or constructor injection (the latter being recommended). 您必须执行
@Autowired
或构造函数注入(建议使用后者)。
Also this: @ComponentScan(basePackages = {"com.goode.service", "com.goode.repository", "com.goode.controller", "com.goode.business", "com.goode"})
Can be replaced by this: @ComponentScan(basePackages = {"com.goode.*"})
还可以这样:
@ComponentScan(basePackages = {"com.goode.service", "com.goode.repository", "com.goode.controller", "com.goode.business", "com.goode"})
可以是替换为: @ComponentScan(basePackages = {"com.goode.*"})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.