簡體   English   中英

如何在XML配置文件中使用Spring Boot自動配置的bean?

[英]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自動配置的DataSourceConnectionFactory 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM