code

XML 구성 파일에서 Spring Boot 자동 구성 빈을 사용하려면 어떻게 해야 합니까?

starcafe 2023. 6. 22. 22:06
반응형

XML 구성 파일에서 Spring Boot 자동 구성 빈을 사용하려면 어떻게 해야 합니까?

XML 구성 파일의 Spring Boot 자동 구성 빈을 일부 활용하고 싶지만, 사용하려고 하면 예외와 오류가 계속 발생합니다.

예를 들어 클래스 경로에 데이터 관련 라이브러리가 있는 경우 Spring Boot이 자동으로 구성합니다.DataSource다음과 같이 내 자신의 콩과 클래스에 자동으로 연결할 수 있는 객체:

@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 구성 파일에서 동일한 작업을 수행하려고 하면 예외가 발생합니다.XML 구성 파일을 추가하여 부트스트랩하고 있습니다.@ImportResource("classpath:xmlconfig.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>

Spring Boot 앱을 실행할 때는 예외입니다.dataSource유효한 자동 구성 Bean 이름입니다.자동 구성으로 이것도 시도해 봤습니다.ConnectionFactory(클래스 경로에 ActiveMQ 포함)EntityManagerFactory클래스 경로에 Hibernate 및 JPA가 있으며 이 중 아무 것도 작동하지 않습니다.

기본적으로 제가 묻고 싶은 것은 스프링 부트 자동 구성 콩을 XML 구성 파일로 자동 배선하는 것과 동등한 것이 무엇입니까?

다음은 모든 문서에 나열된 표준 클래스입니다.

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

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

Java 구성이 아직 제대로 지원되지 않고 프레임워크의 핵심이 XML 구성 기반인 Spring Integration 애플리케이션에서 주로 사용하지만 Spring Boot 자동 구성을 사용하고 싶습니다.DataSource그리고.ConnectionFactory일부 통합 요소에 포함된 콩.

편집: @AdilF가 제공하는 답변은 다음을 위해 작동합니다.dataSource빈, 그러나 유사한 구성은 에 대해 작동하지 않습니다.connectionFactoryBean. 이를 보여주는 데모 코드는 다음 GitHub 프로젝트를 참조하십시오.

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

만약 누군가가 어떻게 적절히 전보를 치는지 알아낼 수 있다면.connectionFactory콩, 정말 감사하겠습니다.

다음은 이를 보여주는 대부분의 코드입니다.

어플.자바

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

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

구성.java

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

FooService.자바

@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");
    }
}

바 서비스.자바

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>

빌드.그래들

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

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;

}

바 서비스

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);
    }
}

푸 서비스

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라는 이름의 빈이 생성되지만 xml은 connectionFactory라는 이름의 빈을 연결하려고 합니다.빈 이름을 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을 사용하려고 하는지 모르겠지만, 그것은 효과가 있습니다.

편집: 스프링 jpa 통합 사용법에 대한 오해가 있을 수 있다는 점도 추가하겠습니다.EntityManagerFactory의 자동 배선이 작동하기는 하지만 직접 사용해서는 안 됩니다.다음과 같이 엔티티 관리자에 연결해야 합니다.

@PersistenceContext
private EntityManager entityManager

나는 그것이 이 질문의 범위를 벗어난다는 것을 알지만, 단지 내가 그것을 추가해야 한다고 생각했습니다.

언급URL : https://stackoverflow.com/questions/25495629/how-can-i-use-spring-boot-auto-configured-beans-in-xml-configuration-files

반응형