[英]Use application.properties in a non-spring injected class
我有一个用new B(this);
在此类 BI 中,想要使用 application.properties 中的值。 但是因为(据我所知)因为它不是用 Spring 创建的,所以不会有任何注入(我使用@Value
注释)
这就是类的创建方式:
@Component
public class A {
public B getB(){return new B(this);}
/**
a lot more stuff
**/
}
有问题的班级:
public class B {
private A a;
public B(A a){
this.a = a;
}
@Value("${threshold}")
private String threshold; //this is null because it's not created with Spring
public String getThreshold(){
return threshold;
}
/**
a lot more stuff
**/
}
所以我的问题如下:
1)如何使用 application.properties 文件中的值或
2)我如何写B,它是用Spring创建的?
一些背景资料:
任何帮助,将不胜感激
这是一个使用@ConfigurationProperties
将application.properties
绑定到 POJO 的示例。
假设你有一个这样的application.properties
文件,
mail.hostname=mailer@mail.com
mail.port=9000
您可以为上述场景创建这样的 POJO。
(注意:如果您的 Spring Boot 版本低于 2.2,您可能还需要使用@Configuration
和@Component
注释此类)
@ConfigurationProperties(prefix = "mail")
public class ConfigProperties {
private String hostname;
private String port;
// Create Getters and Setters
}
当 spring boot 应用程序初始化时,它会自动将application.properties
中的值映射到这个 POJO 中。 如果你想使用它,你所要做的就是创建一个变量并用@Autowire
标记它
@Component
public class TestClass {
@Autowire
private ConfigProperties properties;
public void printSomething() {
System.println(properties.getHostname());
System.println(properties.getPort());
}
}
跟进你的问题...
由于您的示例中的类不是由 spring 管理的,并且由于某种原因您必须保持这种方式,因此您可以使用以下帮助程序类在非 spring 托管类中手动自动装配 spring bean。
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
/**
*Use this method to manually autowire Spring Beans into classes that are not managed by Spring.
*
*@param beanClass - Class type of the required bean.
**/
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
要在class B
中使用它,请执行以下操作。
public class B {
private ConfigProperties properties;
public B() {
BeanUtil.getBean(ConfigProperties.class); // This will initialize properties variable properly.
}
public void printSomething() {
System.println(properties.getHostname());
System.println(properties.getPort());
}
}
你可以写如下:
@Component
public class A {
@Value("${threshold}")
private String threshold;
public B getB(){
return new B(this);
}
public String getThreshold() {
return threshold;
}
}
public class B {
private A a;
private String threshold;
public B(A a){
this.a = a;
this.threshold=a.getThreshold();
}
public String getThreshold(){
return threshold;
}
}
您可以创建一个类,该类将直接从文件中为您加载属性。 该文件必须在资源包中。
定义这些属性的配置属性类
@ConfigurationProperties(prefix = "reader")
public class ReaderProperties {
private String threshold;
}
属性类
import java.util.Properties;
class MyProperties {
private final Properties props;
private MyProperties(Class<?> propertiesClass) throws IOException {
this.props = new Properties();
this.props.load(propertiesClass.getResourceAsStream("/application.properties"));
}
public String getThreshold() {
return props.getProperty("threshold");
}
}
然后在 B 内:
public class B {
private A a;
private String threshold;
public B(A a){
this.a = a;
MyProperties props = new MyProperties(ReaderProperties.class);
this.threshold = props.getThreshold();
}
public String getThreshold(){
return threshold;
}
/**
a lot more stuff
**/
}
如果您愿意并且能够使用@ConfigurationProperties
注释B
类,则现有答案有效,但如果B
作为非 Spring 库的一部分提供,或者如果B
需要在非 Spring 项目中使用,这可能不可行。
幸运的是,如果B
是 POJO/JavaBean,Spring 确实提供了一种更可移植的方法:
示例B
类:
public class B {
private String threshold;
// Is a POJO/JavaBean i.e. has default constructor, getters, setters etc.
}
在application.properties
:
my.config.prefix.threshold=42
在@Configuration
类中为您的 Spring Boot 项目定义一个 Spring bean,例如:
@Configuration
public class ApplicationConfig {
@Bean
@ConfigurationProperties("my.config.prefix")
public B getB() {
// Spring will later use setters to configure the fields per my.config.prefix
return new B();
}
}
您现在可以依靠 Spring 来自动装配依赖关系,例如使用字段注入1 :
@Component
public class A {
@Autowired
private B b; // b.getThreshold() == 42
}
除非一个类严格用于运行或配置 Spring Boot 应用程序,否则我会错误地通过定义 bean 来保持代码更具可移植性。
1一般不推荐现场注入,但为了简洁,这里使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.