有这样一个需求,考虑一个这个类:
@Data
public class RandomFactor
{
String randomFactor;
long createTime = 0;
private RandomFactor(){} //禁止直接构造
public static RandomFactor newOne()
{
RandomFactor ret = new RandomFactor();
ret.randomFactor = random(8, false, true);
ret.createTime = System.currentTimeMillis();
return ret;
}
public boolean expired()
{
return System.currentTimeMillis() - createTime > ?;
}
}
其功能是,对外提供一个随机且有时效的随机串。调用者或任何外部不清楚时效性几何,只需要调用 expired 方法即可知道是否过期。
时效性通过问号处的一个变量控制,此变量希望配置在文件中。
问题来了,当这个类不是一个单例,而是对于每个登录的用户都有一个这样的对象,该类如何设计才能达到目的且满足封闭性?
即言之,? 处的变量不能通过注入的方式引入。如何解决这个问题呢?有个思路。
第一个是,利用 spring 装配非单例的对象,参数可以注入。
第二个是,自己写一个 Bean 工厂,在工厂中注入变量,然后利用此值在需要的时候产生 RandomFactor 对象。
最后一个也就是本文的方法,参见以下代码。个中缘由,细思之。
import static org.apache.commons.lang.RandomStringUtils.random;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import lombok.Data;
@Data
public class RandomFactor
{
String randomFactor;
long createTime = 0;
private RandomFactor(){} //禁止直接构造
public static RandomFactor newOne()
{
RandomFactor ret = new RandomFactor();
ret.randomFactor = random(8, false, true);
ret.createTime = System.currentTimeMillis();
return ret;
}
public boolean expired()
{
return System.currentTimeMillis() - createTime > MockBeanOfRandomFactor.randomFactorTimeoutSecs * 1000;
}
@Component
public static class MockBeanOfRandomFactor
{
public MockBeanOfRandomFactor() {
System.out.println("contruct...");
}
public static int randomFactorTimeoutSecs;
//利用这种方法 ok
@Value("${eek4.randomFactor.timeoutSecs}")
public void set8(int timeoutSecs){
System.out.println("set8");
randomFactorTimeoutSecs = timeoutSecs;
}
@Value("${eek4.randomFactor.timeoutSecs}")
public int timeoutSecs;
//利用这种方法也 ok
@PostConstruct
public void init() {
System.out.println("post construct");
randomFactorTimeoutSecs = timeoutSecs;
}
}
}