web-dev-qa-db-ja.com

XML構成ファイルでSpring Boot自動構成Beanを使用するにはどうすればよいですか?

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を使用)およびEntityManagerFactoryをクラスパスにHibernateとJPAを使用してこれを試しましたが、いずれも機能しません。

基本的に、私が求めているのは、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);
    }
}
_

Java構成はまだ十分にサポートされておらず、フレームワークのコアはXML構成ベースですが、Springを使用したい場合、Spring Integrationアプリケーションでこれを主に使用しています。一部の統合要素で自動構成された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}"
}
_
18
ccampo

次のサンプルコードが役に立ちました。

主な用途

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>
4
Adil F

Autoconfig-testサンプルプロジェクトを使用し、それを機能させることができました。あなたのXMLで見つかった唯一の問題は次のとおりです...

組み込みブローカーを使用することを想定しています。私があなたのプロジェクトを実行したとき、それは自動設定されたものでした...

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

これにより、jmsConnectionFactoryという名前のBeanが作成されますが、xmlはconnectionFactory 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

私はこの質問の範囲を超えていることを知っていますが、それを追加する必要があると考えました

0
hyness