La inyección de constructor y la inyección de Setter, respectivamente, se ocupan de las dependencias circulares.

Una dependencia circular ocurre cuando dos o más beans dependen entre sí. En Spring, la inyección de constructor y la inyección de setter manejan las dependencias circulares de manera diferente. A continuación se describen las estrategias de estos dos métodos de inyección cuando se trata de dependencias circulares.

1. Inyección de constructor

En la inyección del constructor, las dependencias circulares pueden causar problemas porque al crear un bean, Spring necesita llamar al constructor con el parámetro de dependencia. Cuando dos beans dependen uno del otro, Spring no puede crearlos al mismo tiempo, porque la creación de cada bean requiere el otro bean como parámetro. En este caso, Spring no puede resolver la dependencia circular y lanza una excepción BeanCurrentlyInCreationException.

Por ejemplo:

public class FooService {
    
    
    private final BarService barService;

    public FooService(BarService barService) {
    
    
        this.barService = barService;
    }
}

public class BarService {
    
    
    private final FooService fooService;

    public BarService(FooService fooService) {
    
    
        this.fooService = fooService;
    }
}

En el ejemplo anterior, FooService depende de BarService, que a su vez depende de FooService. Dado que ambos inyectan dependencias a través de constructores, Spring caerá en un bucle infinito al crear estos dos beans y, finalmente, lanzará una excepción.

2. Inyección de incubadora

Las dependencias circulares se manejan de manera diferente para la inyección de setter. En este caso, Spring puede resolver el problema de las dependencias circulares. Al usar la inyección Setter, Spring primero crea una instancia del bean y luego inyecta dependencias a través del método setter. Esto significa que cuando se crea un bean, es posible que sus dependencias aún no se hayan inyectado. Spring no marcará el bean como creado hasta que se hayan inyectado todas las dependencias del bean.

Por ejemplo:

public class FooService {
    
    
    private BarService barService;

    public void setBarService(BarService barService) {
    
    
        this.barService = barService;
    }
}

public class BarService {
    
    
    private FooService fooService;

    public void setFooService(FooService fooService) {
    
    
        this.fooService = fooService;
    }
}

En el ejemplo anterior, FooService depende de BarService, que a su vez depende de FooService. Pero dado que ambos inyectan dependencias a través de Setters, Spring primero puede crear instancias de estos dos beans y luego inyectar sus dependencias. De esta forma, Spring puede resolver el problema de las dependencias circulares.

Cabe señalar que la resolución de dependencias circulares puede conducir a un estado de objeto inestable, ya que el estado del bean puede no estar completo hasta que se inyecten todas las dependencias. Esto puede causar errores de tiempo de ejecución o un comportamiento inesperado. Por lo tanto, aunque la inyección de Setter puede resolver el problema de las dependencias circulares, debemos intentar evitar las dependencias circulares.

3. Resumen

La inyección de constructor y la inyección de setter manejan las dependencias circulares de manera diferente. La inyección de constructores no puede resolver el problema de la dependencia circular, porque al crear un bean, Spring necesita llamar a un constructor con parámetros dependientes, lo que da como resultado un bucle infinito y excepciones. La inyección de setter puede resolver dependencias circulares, porque Spring primero creará una instancia del bean y luego inyectará dependencias a través del método setter.

Aún así, las dependencias circulares pueden conducir a un estado de objeto inestable y errores de tiempo de ejecución, por lo que debemos evitarlas. A la hora de diseñar, podemos adoptar las siguientes estrategias para evitar dependencias circulares:

  1. Vuelva a examinar la arquitectura del sistema y el diseño de clases, y divida las clases interdependientes en componentes más pequeños e independientes para lograr un diseño de alta cohesión y bajo acoplamiento.
  2. Utilice patrones de diseño como el modo intermediario y el modo observador para reducir las dependencias directas entre clases.
  3. Utilice la búsqueda de dependencias (Dependency Lookup) u otras funciones avanzadas proporcionadas por los contenedores de inserción de dependencias, como la carga diferida o el uso de proxy, para resolver problemas de dependencia circular en escenarios específicos.

En el desarrollo real, debemos intentar evitar las dependencias circulares para garantizar que el sistema tenga una buena capacidad de mantenimiento y estabilidad. Cuando encuentre problemas de dependencia circular, puede elegir una estrategia de procesamiento adecuada según los requisitos del proyecto y las características de la clase.

Supongo que te gusta

Origin blog.csdn.net/kaka_buka/article/details/129988077
Recomendado
Clasificación