非bean的Spring Boot配置

时间:2019-04-20 19:18:36

标签: spring spring-boot configuration spring-bean

简介

application.yml文件中有一些业务逻辑属性。

它们通过@ConfigurationProperties带注释的类加载到应用程序中。

如何在不是Spring Bean的类中使用这些属性?它不能是单例,因为它的许多对象必须在运行时创建。

示例

application.yml

business.foo: 2

BusinessProperties.java

@ConfigurationProperties("business")
@Getter // lombok
@Setter // lombok
public class BusinessProperties {
    private int foo;
}

TypicalBean.java

@Component
public class TypicalBean {
    private final BusinessProperties properties;

    @Autowired
    public TypicalBean(BusinessProperties properties) {
        this.properties = properties;
    }

    @PostConstruct
    public void printFoo() {
        System.out.println("Foo: " + properties.getFoo()); // "Foo: 2"
    }
}

NonBean.java

public class NonBean {
    public void printFoo() {
        System.out.println("Foo: ???"); // How to access the property?
    }
}

是否有某种方法可以创建非单例类,该类可以访问配置(甚至其他Spring Bean),但其工作方式与常规java类相同?意味着我可以控制其创建,如果不再使用,则由垃圾收集器收集它,等等。

4 个答案:

答案 0 :(得分:0)

所有spring-beans由SpringApplicationContext创建。 Bean-它是简单的POJO对象,但由Spring创建并保存在他的容器中。如果要从容器外部访问bean,请参见:

Getting Spring Application Context

答案 1 :(得分:0)

Spring bean实际上是要在应用程序上下文中使用的,但是您可以通过将属性自动装配到Spring bean中的静态字段来实现所需的功能。

@Component
public class BusinessPropertiesUtils {
    public static BusinessProperties INSTANCE;

    @Autowired
    public setBusinessProperties(BusinessProperties properties) {
        this.INSTANCE = properties;
    }
}

然后:

public class NonBean {
    public void printFoo() {
        System.out.println("Foo: " + BusinessPropertiesUtils.INSTANCE.getFoo());
    }
}

PS:这很hacky,绝对不是“春季之路”。

答案 2 :(得分:0)

您可以使用prototype scope配置Bean,这将在每次请求时为您提供Bean的新实例。 从Spring文档中:

  

与其他作用域相反,Spring不能管理原型bean的完整生命周期。容器将实例化,配置或组装原型对象,然后将其交给客户端,而没有该原型实例的进一步记录。
  ...
  在某些方面,Spring容器在原型作用域Bean方面的角色是Java new运算符的替代。超过该时间点的所有生命周期管理必须由客户端处理。

如何将TypicalBean类转换为原型作用域bean的示例:

@Component
@Scope("prototype")
public class TypicalBean {
   ...
}

另一种方法是手动实例化bean类(或任何POJO),并通过构造函数或setter方法注入依赖项(配置,spring bean等)(如果有),或者可以从Spring Context中获取它们。

new TypicalBean(properties);

答案 3 :(得分:0)

您仍可以使用Scope.Prototype将libxml_get_errors()定义为组件

NonBean.class

诀窍是如何创建@Component @Scope(value = BeanDefinition.SCOPE_PROTOTYPE) public class NonBean { @Autowired public TypicalBean(BusinessProperties properties) { this.properties = properties; } public void printFoo() { System.out.println("Foo: " + properties.getFoo()); } } 的实例。在将创建NonBean.class实例的代码中,使用Spring的NonBean.class

ObjectFactory<T>

实例化的private final ObjectFactory<NonBean> nonBeanFactory; ... NonBean nonBean = nonBeanFactory.getObject(); 对象将被自动装配。