[英]How can I use Spring Boot auto-configured beans in XML configuration files?
我想利用XML配置文件中的一些Spring Boot自動配置的bean,但是當我嘗試這樣做時,我仍然遇到異常和錯誤。
例如,如果我的類路徑上有數據相關的庫,Spring Boot將自動配置一個DataSource
對象,我可以將其自動裝入我自己的bean和類中,如下所示:
@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;
}
}
但是,如果我嘗試在XML配置文件中執行相同操作,我將得到一個例外。 我通過將@ImportResource("classpath:xmlconfig.xml")
到我的主配置類來引導XML配置文件。 這是我正在談論的一個例子......在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>
盡管dataSource
是一個有效的,自動配置的Bean名稱,但上述操作在運行Spring Boot應用程序時會出現異常。 我也嘗試過使用自動配置的ConnectionFactory
(在類路徑上使用ActiveMQ)和在類路徑上使用Hibernate和JPA的EntityManagerFactory
,但這些都不起作用。
基本上,我要問的是:什么相當於將Spring Boot自動配置的bean自動裝配到XML配置文件中?
這是我的主要Spring Boot入口點,只是所有文檔中列出的標准類:
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
我主要在Spring Integration應用程序中使用它,其中Java Configuration尚未得到很好的支持,並且框架的核心是基於XML配置的,但我想使用Spring Boot自動配置的DataSource
和ConnectionFactory
bean。一些集成元素。
編輯:@AdilF提供的答案適用於dataSource
bean,但類似的配置不適用於connectionFactory
bean。 請參閱以下GitHub項目以獲取演示代碼:
https://github.com/ccampo133/autoconfig-test/tree/master
如果有人能弄清楚如何正確connectionFactory
bean,我將不勝感激。
以下是大部分代碼說明:
Application.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>
的build.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}"
}
以下示例代碼適用於我。
主要應用
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>
我使用了你的autoconfig-test示例項目並且能夠使它工作。 我發現你的xml唯一的問題如下......
我假設你想使用嵌入式代理。 當我運行你的項目時,那是自動配置的......
@Bean
public ConnectionFactory jmsConnectionFactory() {
return this.properties.createConnectionFactory();
}
這將創建一個名為jmsConnectionFactory的bean,但是您的xml正在嘗試連接名為connectionFactory的bean。 將bean名稱更改為jmsConnectionFactory修復了...
<bean id="barService" class="app.service.BarService">
<property name="dataSource" ref="dataSource"/>
<property name="connectionFactory" ref="jmsConnectionFactory"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
我不知道你為什么要使用xml,但它確實有用。
編輯:我還會補充說,如何使用spring jpa集成可能會有一些誤解。 盡管EntityManagerFactory的自動裝配確實有效,但實際上不應該直接使用它。 你應該按如下方式連接EntityManager ......
@PersistenceContext
private EntityManager entityManager
我知道它超出了這個問題的范圍,但我想我應該補充一點
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.