Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

93
Visualizações
Bean prototipo de Spring autoconectado parcialmente con argumentos de constructor determinados por el tiempo de ejecución

El javadoc a ConstructorResolver.autowireConstructor(...) dice

También se aplica si se especifican valores de argumento de constructor explícitos, haciendo coincidir todos los argumentos restantes con beans de la fábrica de beans.

pero no puedo hacer que funcione. Obtengo una BeanCreationException :

No se pudo resolver el constructor coincidente (sugerencia: especifique argumentos de índice/tipo/nombre para parámetros simples para evitar ambigüedades de tipo)

En este ejemplo, tengo un bean con un constructor que toma Spring beans así como un String y un int que solo se conocerá en tiempo de ejecución.

 @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class BeanWithRuntimeDependencies { public final DependencyA dependencyA; public final DependencyB dependencyB; public final String myString; public final int myInt; public BeanWithRuntimeDependencies( DependencyA dependencyA, DependencyB dependencyB, String myString, int myInt) { this.dependencyA = dependencyA; this.dependencyB = dependencyB; this.myString = myString; this.myInt = myInt; } } @Component public class DependencyA { /* ... */ } @Component public class DependencyB { /* ... */ }

y mi prueba:

 @RunWith(SpringRunner.class) @SpringBootTest public class PrototypeBeanConstructorsApplicationTests { @Autowired private ApplicationContext context; @Autowired private DependencyA dependencyA; @Autowired private DependencyB dependencyB; @Test public void getBeanFromContext() { BeanWithRuntimeDependencies bean = context.getBean(BeanWithRuntimeDependencies.class, "runtime string", 10); assertNotNull(bean); assertEquals(dependencyA, bean.dependencyA); assertEquals(dependencyB, bean.dependencyB); assertEquals("runtime string", bean.myString); assertEquals(10, bean.myInt); } }

El código fuente de ConstructorResolver.autowireConstructor(...) tiene un comentario:

 // Explicit arguments given -> arguments length must match exactly.

que parece contradecir su javadoc.

¿Es posible hacer esto? ¿Qué estoy haciendo mal?

about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

Parece que no es posible hacerlo de la manera que lo estás haciendo.

En realidad es una situación extraña. De acuerdo con el siguiente fragmento en ConstructorResolver.autowireConstructor(...) ( línea de código fuente #207 ), Spring no considerará a su constructor como candidato para la invocación:

 ... // Explicit arguments given -> arguments length must match exactly. if (paramTypes.length != explicitArgs.length) { continue; }

Y como notó correctamente, realmente contradice la declaración de javadoc:

... haciendo coincidir todos los argumentos restantes con frijoles de la fábrica de frijoles

Pero de todos modos, la implementación significa que, de forma predeterminada, Spring no puede resolver el constructor para crear instancias de dichos beans. Y tienes que crear el método de fábrica manualmente. Algo como:

 @Configuration public class Config{ @Bean @Scope(BeanDefinition.SCOPE_PROTOTYPE) public BeanWithRuntimeDependencies beanWithRuntimeDependencies(String myString, int myInt){ return new BeanWithRuntimeDependencies(dependencyA(), dependencyB(), myString, myInt); } @Bean public DependencyA dependencyA(){ return new dependencyA(); } @Bean public DependencyB dependencyB(){ return new dependencyB(); } }

Entonces puedes obtener bean del contexto como quieras hacer:

 BeanWithRuntimeDependencies bean = context.getBean(BeanWithRuntimeDependencies.class, "runtime string", 10);

Si no quiere tener un trato con la clase de configuración y el método de fábrica, simplemente puede pasar los beans necesarios al context.getBean() . Seguro que tienes que obtener estos frijoles del contexto:

 BeanWithRuntimeDependencies bean = context.getBean(BeanWithRuntimeDependencies.class, context.getBean(DependencyA.class), context.getBean(DependencyB.class), "runtime string", 10);
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda