非bean的Spring Boot配置[重复]

问题描述 投票:0回答:4

这个问题在这里已有答案:

介绍

我在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类相同?这意味着我可以控制它的创建,如果不再使用,它​​将由垃圾收集器收集,等等。

spring spring-boot configuration spring-bean
4个回答
0
投票

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

Getting Spring Application Context


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,绝对不是“春天的方式”。


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);

0
投票

您仍然可以将NonBean.class定义为具有Scope.Prototype的Component

@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的实例。在你将要创建NonBean.class实例的代码中,使用Spring的ObjectFactory<T>

private final ObjectFactory<NonBean> nonBeanFactory;
...
NonBean nonBean = nonBeanFactory.getObject();

实例化的nonBean对象将自动装配。

© www.soinside.com 2019 - 2024. All rights reserved.