anotaciones de primavera Autowired y constructor

mee:

Tengo una clase appuser muelle que tiene un campo anotada @Autowired (de amigos) como tan:

@Getter
@Setter
@Builder
@Document(collection = "app_users")
@Component
public class AppUser {

  @Id
  @NotBlank(message = ErrorConstants.ANDROID_USER_ACCOUNT_MANAGER_ID_IS_NULL)
  private String androidUserAccountManagerId;

  @NotBlank(message = ErrorConstants.NULL_NAME)
  private String name;

  private Friend bestFriend;

  @Autowired
  @Setter(AccessLevel.NONE)
  private FriendList friendList;

  private boolean manualBestFriendOverride;

  public Optional<Friend> getFriend(String friendName) {
    return friendList.getFriend(friendName);
  }

  public void calculateBestFriend() {
    if (!manualBestFriendOverride) {
      bestFriend = friendList.calculateAndReturnBestFriend();
    }
  }
}

La idea era que cada vez que un nuevo appuser fue creado, sería @Autowire el mismo defecto de amigos que empezar de cero.

El appuser se está creando en el método de Controlador Web:

  @PostMapping("/{androidUserAccountManagerId}/setNewAppUser/{appUserName}")
  public void setNewAppUser(
      @NotNull @PathVariable String androidUserAccountManagerId,
      @NotNull @PathVariable @Pattern(regexp = "^[A-z]{2,20}$", message = "Incorrect name format!")
          String appUserName) {
    databaseQueryClass.save(
        AppUser.builder()
            .androidUserAccountManagerId(androidUserAccountManagerId)
            .name(appUserName)
            .build());
  }

Sin embargo, yo estoy haciendo una excepción de puntero nulo lanzada desde cuando el campo está siendo llamada de amigos en otros métodos. Esencialmente no parece el autowiring estar trabajando en conjunto con el constructor appuser.

Después de leer un poco, parece que esta es una mala práctica de llamar o nueva construcción y Autowire un campo en el que se crea una instancia de clase, debido a la COI y la inyección de dependencias están ordenados por primavera.

Mi pregunta es, ¿cómo consigo alrededor de este diseño inteligente? ¿Es posible hacer esto? O debería dejar de intentar Autowire un campo en la nueva instancia tengo que crear? Como alternativa hay una manera que puedo Autowire el nuevo usuario cuando se golpea este punto final?

Gracias por su ayuda por adelantado.

La clase de amigos de contexto:

@ToString
@EqualsAndHashCode
@Builder
public class FriendList {

  @NotNull private List<Friend> listOfFriends;

  public Optional<Friend> getFriend(String friendName) {
    return listOfFriends.stream().filter(o -> o.getName().equals(friendName)).findAny();
  }

  public Friend calculateAndReturnBestFriend() {
    if(listOfFriends.isEmpty()){
      return null;
    }

    java.util.Collections.sort(listOfFriends);
    return listOfFriends.get(0);
  }

  public boolean addToFriendList(String friendName) {
    if (getFriend(friendName).isPresent()) {
      return false;
    }
    return listOfFriends.add(
        Friend.builder().name(friendName).meetingDates(new TreeSet<>()).meetUpNumber(0).build());
  }
}

EDITAR (Lo siento me perdí este contexto ...)

Tengo un grano definido en una clase de AppConfig:

@Configuration
public class AppConfig {

  @Bean
  @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  public FriendList getFriendList() {
    return FriendList.builder().listOfFriends(new ArrayList<>()).build();
  }
}
Andrei Voican:

En cuanto a su @Autowired tema, es muy bien utilizar un nuevo operador o un constructor, siempre y cuando usted deja de contenedores de primavera manejar ese nuevo bean para usted.

Por ejemplo, usted podría hacer algo como:

@Configuration
public class AppConfig {
    @Bean
    public FriendList firendList() {
        return FriendList.builder()
                      //...
                    .build());
    }
}

Y después utilizarlo de esta manera: @Import(AppConfig.class)

Tenga en cuenta , que lo anterior sólo funcionará si el friendlist se crea al principio como un valor por defecto con toda la información disponible en ese momento. Y también que sólo funcionará en el appuser componente que es administrado por la primavera. Si crea el appuser usando constructor en el controlador, es necesario el @Autowired de amigos en el controlador y la puso sobre constructor.

Por otro lado , si los amigos son creados de forma dinámica, y digamos que por el bien del ejemplo que si en el principio usted tiene 10 amigos y después de 1 hora tendrá otros 10 amigos y necesita ver todos los 20 de ellos, entonces necesita otro enfoque. La manera más fácil será tienda en la base de datos de los amigos y simplemente ir a buscar cada uno de ellos cada vez y ponerlos en el appuser. O recuperarlos de una memoria caché de mapa.

También puede utilizar @Autowired en ese escenario, pero es más complicado y tendrá que Autowire directamente una lista de amigos:

@Autowired
private List<Friend> friends;

Y cada amigo se debe crear de forma dinámica. Algo como esto

Friend friend = new Friend(); 
context.registerBean(Friend.class, () -> friend);  //context here is an ApplicationContext type aka Spring Container.

También puedes ver este ejemplo con ObjectProvider desde aquí .

Supongo que te gusta

Origin http://10.200.1.11:23101/article/api/json?id=396032&siteId=1
Recomendado
Clasificación