如何在XML配置文件中使用SpringBoot自动配置bean?
我想利用XML配置文件中的一些Spring Boot自动配置bean,但在尝试这样做时,我总是遇到异常和错误 例如,如果我的类路径上有与数据相关的库,Spring Boot将自动配置一个如何在XML配置文件中使用SpringBoot自动配置bean?,spring,spring-integration,spring-boot,Spring,Spring Integration,Spring Boot,我想利用XML配置文件中的一些Spring Boot自动配置bean,但在尝试这样做时,我总是遇到异常和错误 例如,如果我的类路径上有与数据相关的库,Spring Boot将自动配置一个DataSource对象,我可以将该对象自动连接到我自己的bean和类中,如下所示: @Configuration @ImportResource("classpath:xmlconfig.xml") public class Config { // This works!! @Autowire
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>
我主要在Spring集成应用程序中使用它,Java配置还没有得到很好的支持,框架的核心是基于XML配置的,但是我想在一些集成元素中使用Spring Boot自动配置的DataSource
和ConnectionFactory
bean
编辑:@AdilF提供的答案适用于dataSource
bean,但类似的配置不适用于connectionFactory
bean。请参阅下面的GitHub项目,以获取演示代码:
如果有人能想出如何正确连接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");
}
}
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");
}
}
BarService.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");
}
}
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>
<?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>
下面的示例代码适用于我 主要应用
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">
<!-- THIS WORKS! -->
<property name="dataSource" ref="dataSource"/>
<!-- THIS DOESN'T WORK! -->
<property name="connectionFactory" ref="connectionFactory"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
<?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>
我使用了您的自动配置测试示例项目,并能够使其正常工作。我发现您的xml的唯一问题如下
@PersistenceContext
private EntityManager entityManager
我假设您想使用嵌入式代理。当我运行你的项目时,这是自动配置的
@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>
我知道这超出了这个问题的范围,但我想我应该补充一点您在哪里创建数据源?java配置和xml配置都没有创建数据源。如果启用了
@EnableAutoConfiguration
功能,Spring Boot会自动创建数据源。然后,您可以将其自动连接到JavaConfig bean中。对于初学者来说,应用程序
类需要在已经存在的内容旁边添加@Configuration
注释。基于Java的配置和XML配置的主要区别在于,Java配置基于类型注入,而XML配置基于名称注入。我建议不要创建Config
类,而是将@Configuration
和@ImportResource
中的内容移动到应用程序类中(或者将应用程序
类中的内容移动到配置
类中)。应用程序类用@Configuration
注释。我一定是在邮件里漏掉了。在任何一种情况下,如果我将所有内容都移动到应用程序类,我仍然会遇到相同的问题。@ComponentScan
注释的目的是,我不必将所有bean定义都放在主类中,因此它不应该更改任何内容。您所需要做的就是从应用程序.java
文件中删除@Configuration@ComponentScan@EnableAutoConfiguration
,并将其放在配置.java
上。这对我来说很有效。我的主类启动Spring Boot时已经有了注释集。。。所以这里没有骰子。在我最初的帖子中我应该更清楚,我会继续更新它。在这种情况下,将--debug
选项添加到命令行参数中,并检查spring boot是否拾取了所有配置。如果你可以发布一个github项目来描述这个问题,我可以看一看。当使用--debug
运行时,Boot甚至还不足以抛出autoconfig报告。它似乎是先解析XML文件,然后再做其他任何事情。您是否在thr类路径上有spring boot starter数据jpa
?是的。你有一个简单的项目,在这个工作?我想看看。