绑定两个 属性 类 我需要将它们合并为一个并绑定它
Binding two Property classes and I need to merge them to one and Bind that too
我在一个库中工作,该库通过 application.yml 文件中的 Spring 属性配置 属性 classes。
我正在从已弃用的前缀 (com.myapp.deprecated) 转移到新的前缀 (com.myapp.newprefix)。我想维护已经在短时间内使用已弃用前缀的旧应用程序,以允许迁移期。为了实现这一点,我制作了两个 classes,它们扩展了一个包含共享属性的 class。
*注意我使用的是 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;
}
现在,当我去绑定 属性 文件时,我目前正在将已弃用的 class 和新的 class 绑定到实现 EnvironmentAware 的配置 class 上。
@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);
}
}
我的问题是,我想使用已弃用的属性类并将数据从 class 合并到新的属性类,然后将其绑定到其他 classes 使用。但是,实施 ApplicationContextAware 发生得太晚了,我认为我不能在已经实例化的对象上使用 Binder。我想我可以使用 BeanDefinitionBuilder,但这需要我重新定义对象,并且我会有多个相同类型的 bean 浮动。有没有办法将这两个属性 class 合并在一起,以便我可以将它们用作单个 bean?
我想你可以使用 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);
}
我在一个库中工作,该库通过 application.yml 文件中的 Spring 属性配置 属性 classes。
我正在从已弃用的前缀 (com.myapp.deprecated) 转移到新的前缀 (com.myapp.newprefix)。我想维护已经在短时间内使用已弃用前缀的旧应用程序,以允许迁移期。为了实现这一点,我制作了两个 classes,它们扩展了一个包含共享属性的 class。
*注意我使用的是 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;
}
现在,当我去绑定 属性 文件时,我目前正在将已弃用的 class 和新的 class 绑定到实现 EnvironmentAware 的配置 class 上。
@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);
}
}
我的问题是,我想使用已弃用的属性类并将数据从 class 合并到新的属性类,然后将其绑定到其他 classes 使用。但是,实施 ApplicationContextAware 发生得太晚了,我认为我不能在已经实例化的对象上使用 Binder。我想我可以使用 BeanDefinitionBuilder,但这需要我重新定义对象,并且我会有多个相同类型的 bean 浮动。有没有办法将这两个属性 class 合并在一起,以便我可以将它们用作单个 bean?
我想你可以使用 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);
}