如何在自动装配后调用构造函数?

How to make constructor called after autowired?

我正在构造函数中初始化加载缓存,它需要自动装配参数。但由于 spring bean 序列,我无法正确处理。所以 userLdapGroupsCache 是在没有设置超时和大小的情况下创建的。你们有什么建议来解决这个问题吗?谢谢。

  private LoadingCache<String, Set<String>> userLdapGroupsCache;

  @Autowired
  @Qualifier("cacheExpireTime")
  private int cacheExpireTime;

  @Autowired
  @Qualifier("cacheMaxSize")
  private int cacheMaxSize;

 public LdapAuthorization ()
  {
    userLdapGroupsCache = 
    CacheBuilder.newBuilder()
     .maximumSize(cacheMaxSize)
     .expireAfterWrite(cacheExpireTime, TimeUnit.MINUTES)
     .build(new CacheLoader<String, Set<String>>() {
              @Override
              public Set<String> load(String key) throws Exception {
                return getGroups(key);
              }
            });
  }

您必须将该对象的初始化放在一个用 @PostConstruct:

注释的方法中
  @PostConstruct
  public void init()
  {
    userLdapGroupsCache = 
    CacheBuilder.newBuilder()
     .maximumSize(cacheMaxSize)
     .expireAfterWrite(cacheExpireTime, TimeUnit.MINUTES)
     ...
  }

由于在所有字段都被注入到 bean 中后调用带有 @PostConstruct 注释的方法,因此它将使用注入的参数进行初始化。

似乎字段注入开始不受欢迎了。您可能想使用构造函数注入。与 @PostConstruct 方式相反的好处是您的缓存是最终的。

private final LoadingCache<String, Set<String>> userLdapGroupsCache;

public LdapAuthorization (
  @Qualifier("cacheExpireTime") int cacheExpireTime,
  @Qualifier("cacheMaxSize") int cacheMaxSize
) {
  userLdapGroupsCache = CacheBuilder.newBuilder()
     .maximumSize(cacheMaxSize)
     .expireAfterWrite(cacheExpireTime, TimeUnit.MINUTES)
}

为什么不将 cacheExpireTimecacheMaxSize 传递给构造函数并使这些私有字段成为最终字段。您会发现通过这种行为实现了多个目标。

P.S。看起来你可以在这里使用 lambda:

...
.build(new CacheLoader<String, Set<String>>() {
    @Override
    public Set<String> load(String key) throws Exception {
        return getGroups(key);
    }
});