尝试使用Spring Data JPA使用<repositories />自动生成 DAO 对象,其中 base-package 链接包含 DAO 接口的包,例如:
public interface UserDAO extends JpaRepository<User, String> {
}
但它无法在服务 bean 中连接 DAO 对象,确切的错误是:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ACLService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pkg.service.UserServ pkg.service.ACLServ.userServ; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userServ': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private pkg.repositories.UserDAO pkg.service.UserServ.userDAO; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [pkg.repositories.UserDAO] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
at pkg.config.WebAppInit.onStartup(WebAppInit.java:35)
应用程序引导从WebAppInit.Java开始,因为它实现了 WebApplicationInitializer 接口,web.xml 代码为:
<web-app 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_3_0.xsd" version="3.0"></web-app>
WebAppInit.Java将onStartup 方法编码为:
public class WebAppInit implements WebApplicationInitializer {
public void onStartup(ServletContext container) throws ServletException {
AnnotationConfigWebApplicationContext context =
new AnnotationConfigWebApplicationContext();
context.register(ApplicationContextConfig.class);
context.refresh();
...
然后ApplicationContextConfig类用@Configuration注解,代码为:
@Configuration
@PropertySource("classpath:application.properties")
@ImportResource("classpath:*springDataConfig.xml")
@Import({BasicDataSourceConfig.class,PersistenceSpringDataJpaConfig.class})
@ComponentScan(basePackages={"pkg.service","pkg.utils"})
public class ApplicationContextConfig {
}
所以这只是Java配置的主要/入口点,然后它遵循application.properties(不包括但只是要求它),然后是带有代码的springDataConfig.xml :
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<repositories base-package="pkg.repositories" />
</beans:beans>
BasicDataSourceConfig.Java将DataSource @Bean配置为:
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
...
PersistenceSpringDataJpaConfig.Java将LocalContainerEntityManagerFactoryBean配置为:
@Configuration
public class PersistenceSpringDataJpaConfig {
...
@Autowired
DataSource dataSource;
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
...
如果我切断了删除/注释代码的依赖项,则其他文件没有直接关系:
@Autorire
private UserDAO userDAO
在 UserService 类中;应用程序运行没有错误,我的意思是在访问服务 bean 中的 dao 对象时出现空指针异常。
所以问题是:为什么 Spring Data JPA 不创建 userDAO bean?
PS:我确实故意摆脱了所有@Transactions 管理以简化它,除了它应该在没有事务的情况下工作,不是吗?