Pregunta

¿Hay una manera de convertir automáticamente los beans Spring a la clase definida en el contexto de la aplicación XML? Me gustaría evitar poner información de tipo sobre los beans en 2 lugares ... en el archivo de configuración xml y también en el código como una conversión.

Por ejemplo, dado este archivo de configuración

<bean id="bean-name" class="SimpleSpringBean"  scope="prototype">
    <property name="myValue" value="simple value"></property>
</bean>

¿Puedo llamar a ApplicationContext.getBean (" bean-name ") de tal manera que evite enviar directamente el tipo de devolución a SimpleStringBean . Sé que también puedo llamar a ApplicationContext.getBean (" nombre-bean " ;, SimpleSpringBean.class) para evitar la conversión, pero todavía tengo la información de tipo en 2 lugares.

Parece que Spring puede obtener la información de la clase ( ApplicationContext.getType ) o al obtener el tipo del bean en sí, pero no hay forma de convertir automáticamente el tipo sin la intervención del programador.

¿Fue útil?

Solución

Estoy de acuerdo con Sii, debes evitar llamar a getBean tanto como puedas. Solo conecta tus beans a clases que dependen de ellos.

Aún así, si tiene una sola clase que contiene el contexto de la aplicación, puede proporcionar un método genérico de envoltura como el siguiente:

class MyContextHolder{
    ApplicationContext appContext;
    ......
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName)
    {
        return (T)appContext.getBean(beanName);
    }
}

Entonces puedes llamarlo sin casting

MyClass mc = MyContextHolder.getBean("myClassBean");

Otros consejos

La respuesta es que no deberías usar ApplicationContext.getBean () en absoluto si es posible, y mantenerte con el lugar que tienes que hacer en el código de inicio. (En general, nunca debería necesitar usar getBean () fuera de los puntos de entrada de su aplicación).

Además, lo que estás preguntando es probablemente imposible en el lenguaje Java. Casting es una característica de tiempo de compilación, combinada con una verificación de tiempo de ejecución. El tipo de retorno de getBean () simplemente debe ser conocido en el momento de la compilación. Incluso si Spring puede determinar el tipo de un objeto, no puede cambiar sus propias firmas de método en tiempo de ejecución.

Otra cosa es que incluso si esto fuera posible, la característica no sería tan útil. Debido a que Spring AOP se implementa utilizando proxies dinámicos, casi siempre desea que Spring le entregue una instancia de una interfaz que implementa el bean (que podría ser un proxy AOP), no de la clase de implementación.

Otro enfoque que también utilizo es autowiring la clase de arranque usando:

public class Main {
    @Autowired FooFacade foo;
    @Autowired BarFacade bar;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
        Object main = bf.createBean(Main.class, 
                                    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
                                    false);
        ((Main) main).run();
    }

    private void run() {
        foo.doBootstrapStuff();
        bar.doMoreBootstrapStuff();
    }
}

(Código hecho de la memoria. Podría funcionar solo si tiene el contexto Spring configurado para procesar anotaciones de cableado, en ese caso, los configuradores para foo y barra deberían funcionar. )

La razón principal por la que se desató el getBean es la compatibilidad de Spring (hasta la versión 2.5.x) con Java 1.4. Spring 3.0 eliminará eso y, por lo tanto, ofrecerá el método getBean escrito a continuación.

Sin embargo, debe evitar buscar frijoles directamente y minimizar su uso en la medida de lo posible.

¿Qué pasa si uso Spring como una fábrica de objetos que mi aplicación usa ampliamente? Es decir, en lugar de escribir un montón de clases que ya heredan o envuelven clases de Java conocidas, simplemente decido mover todo eso a un archivo xml para reducirlo Líneas de código Java. Esto significará muchas líneas de xml pero no necesitaré hacer clases esqueléticas de Java que inyecto con Spring o autowire. Así haciendo las líneas. de código Java menos.

Por esta razón, y aún así, como soy nuevo en Spring, tengo lo que he dicho anteriormente. Las publicaciones utilizaron métodos Java estáticos que envuelven los getBeans ().

He trabajado con Spring pero todavía es nuevo para mí, así que perdona mi pregunta.

" Dado que Spring AOP se implementa mediante proxies dinámicos, casi siempre desea que Spring le entregue una instancia de una interfaz que implementa el bean (que podría ser un proxy AOP), no de la clase de implementación "

Por lo tanto, no hay manera de obtener un proxy dinámico utilizando getBean (), ¿cuál es la mejor práctica si no hay interfaces y es una clase de controlador independiente para ser ejecutada?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top