我有一个Spring启动应用程序,可以通过Maven的mvn spring-boot:run
命令运行。但是,当我尝试通过IDE运行它时,在我的情况下是Intellij IDEA 2017.2.1,它失败了,因为它不能@Autowire
数据源。
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.myApp.Application required a bean of type 'javax.sql.DataSource' that could not be found.
Action:
Consider defining a bean of type 'javax.sql.DataSource' in your configuration.
此代码库的原始作者有主类,它启动应用程序,接受数据源的构造函数参数,这是我不熟悉的方法,因为我习惯于通过application.properties
文件执行此操作让Spring Boot连接它自己的DataSource。
@EnableTransactionManagement
@SpringBootApplication
@EnableCaching
public class Application extends JpaBaseConfiguration {
protected Application(DataSource dataSource, JpaProperties properties,
ObjectProvider<JtaTransactionManager> jtaTransactionManagerProvider,
ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
super(dataSource, properties, jtaTransactionManagerProvider, transactionManagerCustomizers);
}
在IDEA中,我注意到此构造函数的datasource
和properties
参数以红色下划线。对于datasource
,IDE抱怨存在两个bean,并且不知道在XADataSourceAutoConfiguration.class
和DataSourceConfiguration.class
之间自动装配哪个bean。至于构造的另一个参数,用红色下划线properties
,它找不到任何bean,IDE抱怨没有找到JpaProperties
类型的bean。以下是在主应用程序启动器类中重写的一些其他方法
@Override
protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
return new HibernateJpaVendorAdapter();
}
@Override
protected Map<String, Object> getVendorProperties() {
Map<String, Object> vendorProperties = new LinkedHashMap<>();
vendorProperties.putAll(getProperties().getHibernateProperties(getDataSource()));
return vendorProperties;
}
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
不幸的是,因为我不熟悉使用构造函数在Spring Boot中配置/自动配置应用程序的方法,我不确定一些事情,但我的确切问题是为什么应用程序与Maven运行良好但在Intellij IDEA中却没有?此外,由于我无法访问这个专有代码库的原作者,我很想知道为什么,如果有人甚至可以给我一个提示,他们已经配置了构造函数,而不是默认的自动配置。我还有一个集成测试,我写的是我试图运行但是这个测试,无论是通过IDE运行还是通过Maven的故障安全插件,都会导致同样的错误DataSource
不是@Autowired
。所以这是另一个问题,为什么这个测试在主应用程序将不会通过Maven运行。这是我的集成测试,
@RunWith(SpringJUnit4ClassRunner.class)
@WebMvcTest(value = TransactionController.class, secure = false)
public class TransactionControllerIT {
@Autowired
MockMvc mockMvc;
@Test
public void shouldInitiateTransfer() {
String transferTransaction =
"some json string I can't show here on stack overflow";
RequestBuilder requestBuilder = MockMvcRequestBuilders
.post("/begin-transfer")
.accept(MediaType.APPLICATION_JSON).content(transferTransaction)
.contentType(MediaType.APPLICATION_JSON);
MvcResult result = null;
try {
result = mockMvc.perform(requestBuilder).andReturn();
} catch (Exception e) {
fail("Exception in integration test!");
}
MockHttpServletResponse response = result.getResponse();
assertEquals(HttpStatus.CREATED.value(), response.getStatus());
}
}
感谢您阅读我的问题。
答案 0 :(得分:5)
您可以轻松地从IDEA运行任何Spring Boot应用程序,执行以下操作:
在Maven面板中,转到插件,展开弹簧启动并右键单击&#34; spring-boot:run&#34;。然后点击&#34;创建您的项目...&#34;如图所示。
这样您就可以从主工具栏中的IDEA以舒适的方式启动应用程序:
这样你仍然使用maven方式,但是集成在IDEA中。我真的不知道你为什么会遇到这些问题。尝试直接执行spring boot app时,我也遇到了一些问题。
答案 1 :(得分:1)
您的测试失败,因为它使用切片测试,@WebMvcTest
这些测试(@DataJpaTest
,JsonTest
)仅加载整个应用程序上下文的一小部分而不是应用程序在启动时执行的所有操作或(@SpringBootTest
)都可以。
使用切片测试时,它将使用任何注释,并需要在@SpringBootApplication
类中定义的任何bean。
E.g。因为您已定义了自动装配的bean,并且将启用任何切片测试缓存和事务管理的两个附加注释,并且始终需要传递这些依赖项。
我不会让你的主应用程序类以这种方式扩展配置类,它过于复杂并且闻起来像XY问题。您应该将配置(和启用注释)外部化到他们自己的@Configuration
类,并将@SpringBootApplication
保留为vanilla,以避免出现这类错误。