create context bean annotation spring spring-integration spring-boot

context - ¿Cómo puedo usar los beans configurados automáticamente Spring Boot en los archivos de configuración XML?



spring xml config annotation (2)

Me gustaría aprovechar algunos de los beans de configuración automática de Spring Boot en los archivos de configuración XML, pero me mantengo con excepciones y errores cuando intento hacerlo.

Por ejemplo, si tengo bibliotecas relacionadas con datos en la ruta de mi clase, Spring Boot configurará automáticamente un objeto DataSource que puedo crear automáticamente en mis propios beans y clases, como por ejemplo:

@Configuration @ImportResource("classpath:xmlconfig.xml") public class Config { // This works!! @Autowired private DataSource dataSource; @Bean public ClassThatRequiresADataSource() { ClassThatRequiresADataSource foo = new ClassThatRequiresADataSource(); foo.setDataSource(dataSource); return foo; } }

Sin embargo, si trato de hacer lo mismo en un archivo de configuración XML, obtendré una excepción. He estado iniciando el archivo de configuración XML al agregar un @ImportResource("classpath:xmlconfig.xml") a mi clase de configuración principal. Aquí hay un ejemplo de lo que estoy hablando ... Dentro de xmlconfig.xml :

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- THIS DOES NOT WORK! --> <bean id="anotherClassThatRequiresADataSource" class="my.package.AnotherClassThatRequiresADataSource"> <property name="dataSource" ref="dataSource"/> </bean> </beans>

Lo anterior dará una excepción cuando se ejecute la aplicación Spring Boot, a pesar de que dataSource es un nombre Bean configurado automáticamente y válido. También he intentado esto con ConnectionFactory configurada automáticamente (con ActiveMQ en la ruta de clase) y EntityManagerFactory con Hibernate y JPA en la ruta de clase, y nada de esto funciona.

Básicamente, lo que pregunto es: ¿cuál es el equivalente a la transferencia automática de beans de configuración de Spring Boot a un archivo de configuración XML?

Aquí está mi principal punto de entrada de Spring Boot es solo la clase estándar que figura en todos los documentos:

@Configuration @ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }

Principalmente utilizo esto en una aplicación Spring Integration, donde la configuración de Java aún no está bien soportada y el núcleo del marco se basa en la configuración XML, pero me gustaría usar los beans DataSource y ConnectionFactory configurados automáticamente con Spring Boot en Algunos de los elementos de integración.

EDITAR: La respuesta proporcionada por @AdilF funciona para el bean dataSource , pero una configuración similar no funciona para el bean connectionFactory . Consulte el siguiente proyecto de GitHub para el código de demostración que ilustra esto:

https://github.com/ccampo133/autoconfig-test/tree/master

Si alguien pudiera descubrir cómo cablear correctamente el bean connectionFactory , se lo agradecería enormemente.

Aquí está la mayoría del código que ilustra esto:

Aplicacion.java

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

Config.java

@Configuration @ImportResource("classpath:/resources/config.xml") public class Config { }

FooService.java

@Service public class FooService { final private Logger logger = LoggerFactory.getLogger(FooService.class); @Autowired private DataSource dataSource; @Autowired private ConnectionFactory connectionFactory; @Autowired private EntityManagerFactory entityManagerFactory; @PostConstruct public void init() { Assert.notNull(dataSource, "dataSource is null!"); logger.info("dataSource not null"); Assert.notNull(connectionFactory, "connectionFactory is null!"); logger.info("connectionFactory not null"); Assert.notNull(entityManagerFactory, "entityManagerFactory is null!"); logger.info("entityManagerFactory is not null"); } }

BarService.java

public class BarService { final private Logger logger = LoggerFactory.getLogger(BarService.class); private DataSource dataSource; private ConnectionFactory connectionFactory; private EntityManagerFactory entityManagerFactory; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public void setConnectionFactory(ConnectionFactory connectionFactory) { this.connectionFactory = connectionFactory; } public void setEntityManagerFactory(final EntityManagerFactory entityManagerFactory) { this.entityManagerFactory = entityManagerFactory; } @PostConstruct public void init() { Assert.notNull(dataSource, "dataSource is null!"); logger.info("dataSource not null"); Assert.notNull(connectionFactory, "connectionFactory is null!"); logger.info("connectionFactory not null"); Assert.notNull(entityManagerFactory, "entityManagerFactory is null!"); logger.info("entityManagerFactory is not null"); } }

config.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="barService" class="app.service.BarService"> <!-- THIS WORKS! --> <property name="dataSource" ref="dataSource"/> <!-- THIS DOESN''T WORK! --> <property name="connectionFactory" ref="connectionFactory"/> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> </beans>

construir.gradle

buildscript { ext { junitVersion = "4.11" springBootVersion = "1.1.5.RELEASE" springIntegrationVersion = "4.0.3.RELEASE" activeMqVersion = "5.7.0" } repositories { mavenCentral() } dependencies { classpath "org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}" } } apply plugin: "java" apply plugin: "eclipse" apply plugin: "idea" apply plugin: "spring-boot" configurations { providedRuntime } jar { baseName = "autoconfig-test" version = "0.0.1-SNAPSHOT" } repositories { mavenCentral() maven { url "http://repo.spring.io/libs-milestone/" } } dependencies { // Spring Boot starters compile "org.springframework.boot:spring-boot-starter-data-jpa:${springBootVersion}" compile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" compile "org.springframework.integration:spring-integration-jms:${springIntegrationVersion}" // ActiveMQ compile "org.apache.activemq:activemq-core:${activeMqVersion}" // Persistence runtime "com.h2database:h2" // Test testCompile "junit:junit:${junitVersion}" }


El siguiente código de ejemplo funcionó para mí.

Aplicación principal

package app; import org.springframework.boot.SpringApplication; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.Assert; import javax.sql.DataSource; public class Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Config.class); DataSource dataSource = context.getBean("dataSource", DataSource.class); Assert.notNull(dataSource); } }

Spring Java Config

package app; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.*; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import javax.sql.DataSource; @Configuration @EnableAutoConfiguration @EnableJpaRepositories @ComponentScan @ImportResource("classpath:config.xml") public class Config { @Autowired private DataSource dataSource; }

BarService

package app.service; import org.springframework.util.Assert; import javax.annotation.PostConstruct; import javax.sql.DataSource; public class BarService { private DataSource dataSource; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } @PostConstruct public void init() { Assert.notNull(dataSource); } }

FooService

package app.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import javax.annotation.PostConstruct; import javax.sql.DataSource; @Service public class FooService { @Autowired DataSource dataSource; @PostConstruct public void init() { Assert.notNull(dataSource); } }

config.xml

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="barService" class="app.service.BarService"> <property name="dataSource" ref="dataSource"/> </bean> </beans>


Utilicé su proyecto de muestra de autoconfig-test y pude hacerlo funcionar. El único problema que encontré con tu xml es el siguiente ...

Supongo que desea utilizar el intermediario incorporado. Cuando ejecuté tu proyecto, eso fue lo que se configuró automáticamente ...

@Bean public ConnectionFactory jmsConnectionFactory() { return this.properties.createConnectionFactory(); }

Esto crea un bean llamado jmsConnectionFactory , sin embargo, su xml está intentando conectar un bean llamado connectionFactory . Cambiando el nombre del bean a jmsConnectionFactory arreglos que ...

<bean id="barService" class="app.service.BarService"> <property name="dataSource" ref="dataSource"/> <property name="connectionFactory" ref="jmsConnectionFactory"/> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean>

No sé por qué querría usar xml, pero funciona.

Edición: También agregaré que puede haber algún malentendido sobre cómo usar la integración de spring jpa. A pesar de que el cableado automático de EntityManagerFactory funciona, realmente no debería usarse directamente. Debe estar cableando un EntityManager de la siguiente manera ...

@PersistenceContext private EntityManager entityManager

Sé que está fuera del alcance de esta pregunta, pero solo pensé que debería agregar eso