使用@Spring Boot中的@Bean配置设置类属性的默认值

huangapple go评论103阅读模式
英文:

Set default value of class property with @Bean configuration in Spring Boot

问题

我想要为下面的类使用 Lombok 的 Builder 设置一个默认的 LocalDateTime它的值应该来自于 @Bean 配置

        @Data
        public class Foo {
    	    @Builder.Default
    	    LocalDateTime created = LocalDateTime.now(clock);
        }

这里是时钟的配置这个值应该在对象初始化时设置

    @Configuration
    public class TimeConfig {
    	public final static String TIME_ZONE = "UTC";
    
    	@Bean
    	public Clock clock() {
    		TimeZone.setDefault(TimeZone.getTimeZone(TIME_ZONE));
    		return Clock.systemUTC();
    	}
    }

我想要实现的目标是自动使用当前时钟设置创建时间戳时钟对于测试有一个静态值
如何让这个工作起来
英文:

I want to set a default LocalDateTime with a Lombok Builder for the following class. Its value should come from a @Bean configuration.

    @Data
    public class Foo {
	    @Builder.Default
	    LocalDateTime created = LocalDateTime.now(clock);
    }

Here the clock configuration. The value should be set when the object is initialized:

@Configuration
public class TimeConfig {
	public final static String TIME_ZONE = "UTC";

	@Bean
	public Clock clock() {
		TimeZone.setDefault(TimeZone.getTimeZone(TIME_ZONE));
		return Clock.systemUTC();
	}
}

What I am trying to achieve is to set a creation timestamp automatically with the current clock. The clock has a static value for tests.
How can I make this work?

答案1

得分: 1

如果您需要在Spring上下文中以及其外部(在lombok中)使用已配置的时钟实例,我会这样做:
首先,通过静态持有者模式创建配置了时区的时钟单例。

public class ClockInstance {
    public final static String TIME_ZONE = "UTC";
    static {
        TimeZone.setDefault(TimeZone.getTimeZone(TIME_ZONE));
    }

    public Clock getClock(){
        return Clock.systemUTC();
    }

    private ClockInstance() {
    }

    private static class Holder {
        private static final ClockInstance INSTANCE = new ClockInstance();
    }

    public static ClockInstance getInstance() {
        return Holder.INSTANCE;
    }
}

然后在您的Spring配置中使用此时钟实例。

@Configuration
public class TimeConfig {

    @Bean
    public Clock clock() {
        return ClockInstance.getInstance().getClock();
    }
}

然后您可以在您的Foo类中使用这个正确配置的时钟。

@Data
public class Foo {
    @Builder.Default
    LocalDateTime created = LocalDateTime.now(ClockInstance.getInstance().getClock());
}

这种方法有一些不足之处,例如您不能轻松地将此时钟实例替换为用于测试的某个固定时钟,因此您需要在测试中更改created字段,例如通过Foo类的构造函数。

英文:

If you need to use this clock configured instance in spring context and outside of it (in lombok)
then I will do it like this:
First create a singleton of Clock with configured time zone through static holder pattern

public class ClockInstance {
    public final static String TIME_ZONE = "UTC";
    static {
        TimeZone.setDefault(TimeZone.getTimeZone(TIME_ZONE));
    }

    public Clock getClock(){
        return Clock.systemUTC();
    }

    private ClockInstance() {
    }

    private static class Holder {
        private static final ClockInstance INSTANCE = new ClockInstance();
    }

    public static ClockInstance getInstance() {
        return Holder.INSTANCE;
    }
}

Then use this clock instance in your spring configuration

@Configuration
public class TimeConfig {

    @Bean
    public Clock clock() {
        return ClockInstance.getInstance().getClock();
    }
}

And you will be able to use this correct configuration of clock in your Foo class

@Data
public class Foo {
    @Builder.Default
    LocalDateTime created = LocalDateTime.now(ClockInstance.getInstance().getClock());
}

This approach have some downsides, for example you cannot easly replace this clock instance for test to some fixed clock, so you will need to change created field in your tests, for example through a constructor of Foo class

huangapple
  • 本文由 发表于 2020年10月17日 22:32:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/64403599.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定