如何建议获取不可变对象以使用这种方式构建此对象



我怎样才能让不可变的东西生成一个这样的类

public class IdentifiedUserDetails implements UserDetails, CredentialsContainer, Identified<UUID> {
private static final long serialVersionUID = 4905378177558522349L;
private final UUID id;
private final String username;
private final Set<GrantedAuthority> authorities;
private boolean accountNonExpired = true;
private boolean accountNonLocked = true;
private boolean credentialsNonExpired = true;
private boolean enabled = true;
private String password;
IdentifiedUserDetails( final UUID id, final String username, final String password ) {
this.id = Objects.requireNonNull( id );
this.username = Objects.requireNonNull( username );
this.password = Objects.requireNonNull( password );
this.authorities = Collections.unmodifiableSet( sortAuthorities( Collections.emptySet() ) );
}
private static SortedSet<GrantedAuthority> sortAuthorities(
final Collection<? extends GrantedAuthority> authorities ) {
// Ensure array iteration order is predictable (as per
// UserDetails.getAuthorities() contract and SEC-717)
return authorities.stream()
.filter( Objects::nonNull )
.collect( Collectors.toCollection( () -> {
return new TreeSet<GrantedAuthority>(
Comparator.nullsFirst( Comparator.comparing( GrantedAuthority::getAuthority ) ) );
} ) );
}
}

注意:空集是从某个外部数据源传入的实际集的占位符,我还没有开始填充它,但我会在某个时候填充它,并且排序是 Spring Security 中排序的重新实现,您应该假设该排序需要应用于将传递给不可变构建器的任何集合。

关于如何使用不可变注释处理器实现这一目标,有很多变化,因为我了解您要实现的目标;)

不可变支持开箱即用的SortedSet,但仅使用自然排序(请参阅@Value.NaturalOrder@Value.ReverseOrder)。如果要应用特殊比较器,不可变将仅允许您自己构建集合并将其设置到构建器上。从示例来看,排序是特定于对象实现的,因此我将跳到其他选项。

有强大(但有点容易出错)的功能可以使用@Value.Check方法启用对象的规范化/规范化。指南中对此进行了描述:http://immutables.github.io/immutable.html#normalization。但是,由于需要检查集合/集合是否已排序,因此使用规范化有点复杂。

最后,我会提出另一种更简单的方法,我已经将其用于类似的目的。@Value.Derived注释允许您在对象构造期间构建数据的替代视图。在这种情况下,将有集合用作初始化缓冲区和此数据的计算替代视图。计算将在构造过程中发生,此后不可变的对象将永远不会更改。我们将使用访问和属性名称来使其看起来不错。下面是示例:

@Value.不可变 public abstract class IdentificationUserDetails 实现 UserDetails, CredentialsContainer, Identification{ 私有静态最终长串行版本UID = 4905378177558522349L; 公共抽象 UUID getId(); 公共抽象字符串 get用户名(); public abstract String getPassword(); 为简洁起见,省略了其他属性//... 摘要 @SkipNulls 列表<授予权限>权威(); @Value.派生 public SortedSetgetAuthority() { 返回 authority().stream() .collect(Collectors.toCollection(() -> { 返回新的树集( Comparator.nullsFirst(Comparator.comparing(GrantedAuthority::getAuthority))); })); } } public static void demo(GrantedAuthority ga1, GrantedAuthority ga2) { 已识别用户详细信息详细信息 = ImmutableIdentificationUserDetails.builder() .id(UUID.randomUUID()) .用户名("名称") .password("字符串")//... .addAuthority(ga1) .addAuthority(ga2) .build(); SortedSetsortedAuthorities = details.getAuthority(); }

附言@SkipNulls是一种 BYOAnnotation。如果需要,请创建它,它将通过一个简单的名称进行识别。

最新更新