我正在将 Spring Java Web 项目的基于 XML 的配置转换为 JavaConfig。
我正在使用 JPA。所以我用必要的配置创建了一个额外的 JavaConfig 类。但是由于某种原因,JPA 配置失败了。
这是我的 [web.xml][1]
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<!-- Configuration locations must consist of one or more comma- or space-delimited
fully-qualified @Configuration classes. Fully-qualified packages may also be
specified for component-scanning -->
<!-- <context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.contoso.spring.contosoJPA</param-value>
</context-param>-->
<!-- Bootstrap the root application context as usual using ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Declare a Spring MVC DispatcherServlet as usual -->
<servlet>
<servlet-name>restservices</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
instead of the default XmlWebApplicationContext -->
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<!-- Again, config locations must consist of one or more comma- or space-delimited
and fully-qualified @Configuration classes -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.my.contoso.spring.contosoConfig</param-value>
</init-param>
</servlet>
<!--
This Servlet mapping means that this Servlet will handle all incoming requests
-->
<servlet-mapping>
<servlet-name>restservices</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- for CORS -->
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Content-Type, X-Requested-With, Origin, Accept</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- End for CORS -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<filter>
<filter-name>OpenEntityManagerFilter</filter-name>
<filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
<init-param>
<param-name>entityManagerFactoryBeanName</param-name>
<param-value>entityManagerFactory</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>OpenEntityManagerFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- <resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/contosoDS</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>-->
</web-app>
这是我的主要 [JavaConfig 类][2]
@Configuration
@EnableWebMvc
//@ImportResource("contoso-jpa.xml") //Import any existing xml context files
@Import(contosoJPA.class)
//@EnableTransactionManagement //substitute for <tx:annotation-driven/>
@ComponentScan({"com.my.contoso.webservices.rest", "com.my.contoso.services,com.my.contoso.dao"})
public class contosoConfig {
}
这是带有 [JPA config][3] 的 JavaConfig 类
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories //(basePackages = { "com.my.contoso.domain" })
public class contosoJPA {
@Bean
public DataSource dataSource() {
// return new EmbeddedDatabaseBuilder().setType(H2).build();
DriverManagerDataSource ds = new DriverManagerDataSource();
try {
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("root");
ds.setPassword("");
ds.setUrl("jdbc:mysql://localhost:3306/contosodb");
} catch (Exception e) {
// logger.error(e.getMessage());
System.out.println(e);
}
return ds;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(jpaVendorAdapter);
lef.setPackagesToScan("com.my.contoso.domain");
lef.setPersistenceUnitName("contosoPU");
return lef;
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(true);
hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
// hibernateJpaVendorAdapter.setDatabase(Database.H2);
return hibernateJpaVendorAdapter;
}
@Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
}
全栈跟踪:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'entityManagerFactory' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1108)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:278)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1121)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:222)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.lookupEntityManagerFactory(OpenEntityManagerInViewFilter.java:205)
at org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.doFilterInternal(OpenEntityManagerInViewFilter.java:152)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:179)
at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:241)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2430)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2419)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:570)
'entityManagerFactory' 在 [web.xml][1] 中声明。该错误表明不存在具有此类名称的 bean。但我确实将它包含在 [JPA config][3] 文件中。所以我猜测 JPA javaConfig 文件中的 bean 没有被拾取。想知道配置失败的地方。