【问题标题】:Dynamic bean update once it has instantiated during the Spring Boot start up在 Spring Boot 启动期间实例化后的动态 bean 更新
【发布时间】:2018-11-16 21:20:23
【问题描述】:

我在 Spring Boot 应用程序启动期间设置了一个 bean。我正在尝试使用休息端点更新 bean。控制器中的端点调用 updatePoints()。当我使用 GET 点检索数据时,它仍然只有在启动期间实例化的数据。它在 bean 中没有更新的数据。

@Component
public class DynamicEntry{

private Map<String, DynamicPoint> dynamicPoints = new HashMap<>();
private DefaultListableBeanFactory beanFactory;

@Autowired
public DynamicEntry(DefaultListableBeanFactory beanFactory){
    this.beanFactory = beanFactory;
}

@PostConstruct
 void loadPoints(){
        //load the dynamicPoints after the spring boots up
}

void updatePoints(String point){
try {
     if (!dynamicPoints.containsKey(point)) {
                DynamicPoint dynamicPoint = new DynamicPoint(point);
                beanFactory.registerSingleton(point, dynamicPoint);
                dynamicPoints(point, dynamicPoint);
}
} catch (Exception | Error e) {
            e.printStackTrace();
}
}

@Bean
    public Map<String, DynamicPoint> dynamicPoints() {
        return dynamicPoints;
    }
}

【问题讨论】:

    标签: spring spring-boot autowired spring-bean


    【解决方案1】:

    你可以尝试用ConfigurableApplicationContext.refresh()刷新:

    beanFactory.registerSingleton(point, dynamicPoint);
    beanFactory.refresh();
    

    但会有副作用,例如重新创建现有的单例,这可能会导致您的应用程序停机或无法将响应发送回客户端。

    你想要达到的目标是非常不标准的。按照设计,单例 bean 定义是在启动期间处理的。您应该重新考虑您的方法,并且不要在运行中创建单例 bean。也许您需要一个请求或会话范围的 bean?

    【讨论】:

    • 有没有其他方法可以更新启动时实例化的 bean?
    • @Harish 您可以使用@Autowired 获取现有的bean 实例并在其上调用setter 以更改其字段值,但不建议创建新bean。这可能是可行的,但您的问题中没有足够的信息来提出解决方案。
    • 我尝试对现有的 bean 实例使用 @Autowired 并尝试向地图添加一个条目。数据已更新。但是当我尝试检索数据时,它仍然向我显示了 Spring Boot 实例化时的数据。
    • @Harish 请提供一个工作示例来说明问题,从您的问题中不清楚您到底尝试了什么。
    猜你喜欢
    • 1970-01-01
    • 2019-05-15
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 2016-06-13
    • 1970-01-01
    相关资源
    最近更新 更多