es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

@ConfigurationProperties, @Value no funcionan AÚN pasando las pruebas.

Tengo un problema extraño leyendo la configuración, ninguna de las soluciones que he visto parece funcionar. Aquí está mi código:

@SpringBootApplication
@EnableConfigurationProperties
public class Application {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

}

Aquí está mi clase de propiedades:

@Component
@ConfigurationProperties(prefix = "my")
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class MyProperties {
    private String host;
    private int port;
}

Luego uso la clase MyProperties en mi clase usando @Autowired:

@Autowired
private MyProperties props;

Sin embargo, estoy obteniendo null para mi objeto props.

Extrañamente, esto está pasando las pruebas perfectamente:

@SpringBootTest
class ApplicationTests {

@Autowired
private MyProperties props;

@Test
void test_configuration() {
    Assertions.assertEquals(props.getHost(), "xx.xx.xx.xx");// ¡Pasa!
    Assertions.assertEquals(props.getPort(), xxxxxx);// ¡Pasa!
}
}

Se ha negado rotundamente a funcionar, al igual que la inyección de @Value. ¿Qué podría estar pasando?

EDICIÓN

Aquí está el código completo de cómo estoy usando @Autowired en MyProperties (también he incluido @Value que tampoco funciona):

@Slf4j
@Component // también he probado con @Configurable, @Service
public class MyService {

@Autowired
private MyProperties props;

@Value("localhost")
public String host;

public void post() {
    log.info(host + props);// = null y null
}
}

EDICIÓN2

Sin embargo, he notado que en el controlador, funciona perfectamente:

@Slf4j
@RestController
@Service
public class Main {

@Autowired
private MyProperties props;

@Value("localhost")
private String host;

@GetMapping("/post")
public void post() {
    log.info(host + props);// = ¡es perfecto!
    new MyService().post();// llamando a MyService - donde @Autowired o @Value falla
}
}
Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema puede estar en cómo estás utilizando MyService e inyectando MyProperties en él. Si creas una nueva instancia de MyService usando new, Spring no sabrá cómo inyectar MyProperties en ella. Deberías crear un bean para MyService e inyectarlo donde lo necesites.

    Aquí tienes un ejemplo de cómo puedes crear un bean para MyService:

    @Slf4j
    @Component
    public class MyService {
    
        private final MyProperties props;
        private final String host;
    
        public MyService(MyProperties props, @Value("localhost") String host) {
            this.props = props;
            this.host = host;
        }
    
        public void post() {
            log.info(host + props);
        }
    }
    

    En tu clase de configuración, puedes crear un bean para MyService de la siguiente manera:

    @Configuration
    public class AppConfig {
    
        @Bean
        public MyService myService(MyProperties props, @Value("localhost") String host) {
            return new MyService(props, host);
        }
    }
    

    Luego, puedes inyectar MyService en otros beans usando @Autowired:

    @Slf4j
    @RestController
    @Service
    public class Main {
    
        private final MyProperties props;
        private final String host;
        private final MyService myService;
    
        public Main(MyProperties props, @Value("localhost") String host, MyService myService) {
            this.props = props;
            this.host = host;
            this.myService = myService;
        }
    
        @GetMapping("/post")
        public void post() {
            log.info(host + props);
            myService.post();
        }
    }
    

    Con este enfoque, Spring debería inyectar correctamente MyProperties en MyService y en Main.

Comments are closed.