2011-04-07 14 views
5

Dado que tengo un grano de primavera configurado comocómo sobrescribir los granos de servicios de Primavera por su nombre, utilizando anotaciones única

@Service("myService") 
public class DefaultService extends MyService { 
} 

y una clase usando este bean

public class Consumer { 
    @Autowired 
    @Qualifier("myService") 
    private MyService service; 
    ... 
} 

ahora quiero mi proyecto, que incluye las clases anteriores, para tener Consumer se está inyectando otra implementación de MyService. Por lo tanto me gustaría sobrescribir el bean myService

@Service("myService") 
public class SpecializedService implements MyService { 
} 

resultante en Consumer llevar ahora una instancia de SpecializedService en lugar de DefaultService. Por definición, no puedo tener dos frijoles con el mismo nombre en el contenedor de Spring. ¿Cómo puedo decir en primavera que la definición del nuevo servicio sobrescribirá al anterior? No quiero modificar la clase Consumer.

Respuesta

2

De cualquier definen el servicio de frijol explícitamente

<bean id="myService" class="x.y.z.SpecializedService" /> 

o componente de escanearlo.

En cualquier caso, en el contexto de su aplicación, evite definir explícitamente DefaultService y evite el escaneo de componente.

+0

Gracias, Willie. Terminamos con su solución ya que también decidimos por razones de mantenimiento (estamos hablando de cientos de servicios) mantener la lista de cada servicio en un solo archivo, a saber, la configuración de Spring Bean. Definir solo ID y el nombre de clase no es demasiado doloroso, ya que usar anotaciones solo es más tentador. –

2

excluirlo del componente de exploración mediante el uso de un filtro

<component-scan base-package="your-package"> 
    <exclude-filter type="regex" expression="DefaultService" /> 
</component-scan> 

No estoy seguro si hay una manera de hacerlo con sólo anotaciones (con excepción de la eliminación de la anotación de @Service DefaultService).

+0

Gracias, Wilhelm, estoy seguro de que su solución funcionaría. Pero luego tendría que escanear mis servicios por mi cuenta. ¡Buena idea! –

0

El cableado basado en anotaciones ocurre antes de la configuración basada en XML, lo que significa que los beans definidos en XML sobrescribirán aquellos alambrados hechos por Anotaciones. Así definirlo explícitamente en XML, como ha dicho Willie va a hacer el trabajo

<bean id="myService" class="x.y.z.SpecializedService" /> 

primavera recomienda el uso de XML para el servicio de repositorio y frijoles y anotación para los granos de MVC. También recomienda @Autowired sin escaneo de componentes. Pero, en general, se alienta la anotación, aunque combina el código y la configuración (contra la separación de preocupaciones).

En segundo lugar es utilizar @Qualifiers ("id of declarated bean") donde se está pasando.

-2

Lo sé, es tarde. Aún publicando.

Debe tener diferentes nombres para diferentes implementaciones de MyService.

Por ejemplo

@Service("mySpecializedService") 
public class SpecializedService implements MyService { 
} 

@Service("myService") 
public class DefaultService extends MyService { 
} 

Mientras Autowiring ellos (digamos en el controlador), se puede utilizar para inyectar @Qualifier aplicación deseada como se menciona a continuación.

Para obtener la aplicación por defecto

@Autowired 
@Qualifier("myService") 
MyService myService; 

Para llegar aplicación especializada

@Autowired 
@Qualifier("mySpecializedService") 
MyService myService; 
+0

Esto es completamente contrario a lo que OP solicitó. –

+0

@HimanshuBhardwaj ... ¿Podría compartir su enfoque ...? – user6087330

+0

Habría definido un bean nuevo sobre el otro en un archivo de configuración separado (xml o java), y dejaría que se reemplazara al anterior, o hubiera seguido adelante con Spring Profiles o @Conditional. –

Cuestiones relacionadas