2

我正在一个库中工作,该库通过 application.yml 文件中的 Spring 属性配置属性类。

我正在从不推荐使用的前缀(com.myapp.deprecated)转移到新的前缀(com.myapp.newprefix)。我想暂时保留已经使用过时前缀的旧应用程序,以允许迁移期。为了实现这一点,我制作了两个类来扩展一个包含共享属性的类,就像这样。

*注意我使用lombok,所以它们上面会有@Data 注释。

public class BasePropertyClass {
    private String sharedProperty1;
    private String sharedProperty2;
}

@ConfigurationProperties("com.myapp.deprecated")
public class DeprecatedPropertyClass extends BasePropertyClass {

}

@ConfigurationProperties("com.myapp.newprefix")
public class newPropertyClass extends BasePropertyClass {
    private String newProperty;
}

现在,当我去绑定属性文件时,我目前正在将不推荐使用的类和新类绑定到实现 EnvironmentAware 的配置类上。

@Configuration
public class ConfiguringClass implements EnvironmentAware {
    @Override
    public void setEnvironment(Environment environment) {
        
        DeprecatedPropertyClass deprecatedPropertyClass = Binder
            .get(environment)
            .bind("com.myapp.deprecated", DeprecatedPropertyClass.class)
            .orElse(null);

        newPropertyClass newPropertyClass = Binder
            .get(environment)
            .bind("com.myapp.newprefix", newPropertyClass.class)
            .orElse(null);
    }
}

我的问题是,我想采用 DeprecatedPropertyClass 并将该类中的数据合并到 newPropertyClass,然后将其绑定到上下文以供其他类使用。但是,实现 ApplicationContextAware 发生得太晚了,我认为我不能在已经实例化的对象上使用 Binder。我想我可以使用 BeanDefinitionBuilder 但这将需要我重新定义对象,并且我会有多个相同类型的 bean 浮动。有没有办法将这两个 Properties 类合并在一起,以便我可以将它们用作单个 bean?

4

1 回答 1

1

我认为您可以使用org.springframework.beans.BeanUtils. 它已copyProperties(T source, T target);用于复制属性。

    public static void myCopyProperties(Object source, Object target) {
       BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

getNullPropertyNames(src)用于忽略 null 属性。

    public static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }

        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }
于 2021-10-27T19:39:21.230 回答