Как бы посоветовали получить Immutables для создания этого объекта с такого рода
Как я мог заставить Immutables генерировать класс с такого рода
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 ) ) );
} ) );
}
}
примечание: пустой набор - это заполнитель для реального набора, переданного из какого-то внешнего источника данных, я еще не начал его заполнять, но в какой-то момент я сделаю это, и сортировка - это повторная реализация той, что в весенней безопасности, Вы должны предположить, что сортировку необходимо применить к любому набору, который будет передан сборщику Immutables.
1 ответ
Есть много вариантов того, как вы можете добиться этого, используя процессор аннотаций Immutables, учитывая, что я понимаю, чего вы пытаетесь достичь;)
Неподвижные опоры SortedSet
из коробки, но только используя естественный порядок (см. @Value.NaturalOrder
а также @Value.ReverseOrder
). Если вы хотите применить специальный компаратор, Immutables позволит вам только построить набор самостоятельно и установить его на строителя. Судя по примеру, желательно, чтобы упорядочение было чем-то конкретным для реализации объекта, поэтому я перейду к другим вариантам.
Существует мощная (но несколько подверженная ошибкам) функциональность, позволяющая нормализовать / канонизировать объект с помощью @Value.Check
метод. Это описано в руководстве: http://immutables.github.io/immutable.html. Однако использование нормализации немного усложняется необходимостью проверить, отсортирован ли набор / коллекция.
В конце я бы предложил еще один, более простой подход, который я использовал для аналогичных целей. @Value.Derived
аннотация позволяет построить альтернативное представление данных во время построения объекта. В этом случае будет использоваться коллекция, используемая в качестве буфера инициализации, и вычисленное альтернативное представление этих данных. Вычисления произойдут во время строительства, и неизменный объект никогда не изменится после этого. Мы будем играть с именами доступа и атрибутов, чтобы они выглядели красиво. Вот пример:
@ Value.Immutable открытый абстрактный класс IdentifiedUserDetails реализует UserDetails, CredentialsContainer, Identified{ приватный статический финал long serialVersionUID = 4905378177558522349L; открытый абстрактный UUID getId(); public abstract String getUsername(); public abstract String getPassword(); // другие атрибуты опущены для краткости // ... abstract @SkipNulls List полномочия (); @ Value.Derived public SortedSet getAuthorities () { вернуть полномочия ().stream() .collect(Collectors.toCollection(() -> { вернуть новый TreeSet( Comparator.nullsFirst(Comparator.comparing(GrantedAuthority::getAuthority))); })); } } публичная демонстрация статической пустоты (GrantedAuthority ga1, GrantedAuthority ga2) { IdentifiedUserDetails details = ImmutableIdentifiedUserDetails.builder() .id(UUID.randomUUID()) .username("Name") .password("Строка") //... .addAuthority(GA1).addAuthority (GA2).build (); SortedSet sortedAuthorities = details.getAuthorities (); }
PS @SkipNulls
это своего рода аннотация. При необходимости создайте его, и оно будет распознано по простому имени.