Al realizar la depuración con puntos de interrupción, noté que el orden de ejecución de los métodos anotados de @Bean no está realmente relacionado con su relación de dependencia. Por ejemplo:
@Configuration public class config { @Bean (name = "myDataSource") public DataSource dataSource() {return new HikariDataSource();} @Bean public TransactionManager transactionManager(@Qualifier("myDataSource") DataSource dataSource) { return new TransactionManager(dataSource); } @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {...} } El método transactionManager o sqlSessionFactory siempre se ejecuta antes que el método dataSource() en mi aplicación. Me aseguré de que no haya una configuración automática de la fuente de datos ni ningún otro código que pueda haber creado otra fuente de datos.
Y el comportamiento de la aplicación es correcto, puede conectarse a la base de datos correcta y recuperar datos.
Este comportamiento extraño podría tener algo que ver con múltiples fuentes de datos. Configuré más de 1 fuente de datos en mi aplicación.
Sé que Spring tiene un mecanismo similar cuando se trata de dependencias cíclicas. Digamos que las clases A y B dependen una de la otra, y al crear el Bean A, Ab se establecerá en una instancia vacía de B. Lo mismo ocurre con B.
Aquí asumo que cuando se ejecuta el método sqlSessionFactory() , se creará y se le pasará un origen de datos vacío. Y ese origen de datos más tarde hará referencia/proxy bean "myDataSource".
Quiero saber si mi suposición es correcta o si alguien puede explicar claramente el comportamiento.
Editar
Así es como se ve mi punto de depuración: 
Entonces, el método transactionManager() siempre se ejecuta primero. Y en este momento, el origen de datos inyectado ( dataSource ) sigue siendo nulo.
Pero después de que la aplicación se inicia y realiza consultas a la base de datos, utiliza el origen de datos correcto:
Mi otra fuente de datos se llama orderDataSource y el mapeador la está refiriendo correctamente.
Me refiero a que, por fin transactionManger y sqlSessionFactory usan mis fuentes de datos especificadas, satisfaciendo lo que exige mi anotación; de lo contrario, sería un error de Spring y la aplicación no podría funcionar. Pero cuando el subproceso principal está inicializando esos beans, el método dataSource() se ejecuta en último lugar. Lo descubro en modo de depuración. Estoy tratando de entender el mecanismo subyacente aquí.
Si desea especificar un orden específico, puede usar @DependsOn
Deberíamos usar esta anotación para especificar las dependencias de los beans. Spring garantiza que los beans definidos se inicializarán antes de intentar una inicialización del bean actual.
Si desea que myDataSource se inicialice primero, defina @DependsOn({"myDataSource"})
@DependsOn({"myDataSource"}) @Bean public TransactionManager transactionManager(@Qualifier("myDataSource") DataSource dataSource) { return new TransactionManager(dataSource); } @DependsOn({"myDataSource"}) @Bean public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {...}Beans de los que depende el bean actual. Se garantiza que cualquier frijol especificado será creado por el contenedor antes de este frijol.
Aquí asumo que cuando se ejecuta el método sqlSessionFactory(), se creará y se le pasará un origen de datos vacío. Y ese origen de datos más tarde hará referencia/proxy bean "myDataSource". Quiero saber si mi suposición es correcta o si alguien puede explicar claramente el comportamiento.
Para responder a esta pregunta, debemos analizar el ciclo de vida de creación de beans .
Tenga en cuenta que la creación de instancias ocurre primero, mucho antes que todo lo demás. Aquí es donde se ejecutan los métodos anotados de @Bean .
Ahora es importante darse cuenta de que Spring no siempre inyecta sus dependencias directamente, sino que puede inyectar proxies , que envuelven sus beans. Esto es necesario para que funcione algo de la magia de Springs como AOP .
Para ver con precisión lo que se está inyectando en sus métodos @Bean , puede establecer un punto de interrupción de depuración en estos métodos. El simple uso de toString() no funcionará... solo te dirá que es un objeto ordinario (el proxy intenta ocultar que está ahí jajaja...)
Si investigas con el depurador, sin embargo… verás esto…
Ver ? No hay ninguna instancia del objeto A que se inyecte. Se inyecta un proxy.
Entonces, Spring hace esto en su caso... crea estos beans con métodos @Bean y solo le da a cada uno un proxy de la dependencia. Luego, dado que Spring tiene referencias a todos los beans y proxies... los conecta descifrando el gráfico de dependencia a través de un algoritmo similar a la ordenación topológica .
Si algo aún no está claro, por favor deje un comentario y lo ampliaré.
También ayudaría si pudiera mirar en el depurador en el ejemplo anterior para ver exactamente qué se está inyectando en sus métodos en lugar del bean DataSource en ambos casos.
Esto nos permitirá identificar con precisión lo que está pasando.