具有休眠 CRUD 操作的 Spring 3 注释:@Autowired 未按预期工作

Posted

技术标签:

【中文标题】具有休眠 CRUD 操作的 Spring 3 注释:@Autowired 未按预期工作【英文标题】:Spring 3 Annotations with hibernate CRUD operations : @Autowired not working as expected 【发布时间】:2015-11-02 03:06:00 【问题描述】:

我目前正在使用 Spring 3 注释和 hibernate 3 进行数据库连接。我还必须使用弹簧砖。 我的 spring-servlet.xml 是:

    <context:annotation-config />
<context:component-scan base-package="com.xxx.controller,com.xxx.dao,com.xxx.service" />

<mvc:annotation-driven />

<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver"
    id="viewResolver">
    <property name="viewClass">
        <value>
            org.springframework.web.servlet.view.tiles2.TilesView
        </value>
    </property>
</bean>
<bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer"
    id="tilesConfigurer">
    <property name="definitions">
        <list>
            <value>/WEB-INF/plugin/impl/tiles/springtiles-defs.xml</value>
        </list>
    </property>
</bean>

//Is this required????
<!-- <bean id="MyDAO" class="com.xxxx.MyDAOImpl"></bean>
<bean id="MyService" class="com.xxxx.MyServiceImpl"></bean> -->

我的控制器类:

@Controller
public class myController 

    @Autowired
    private MyService myService;
    public myController() 

    

    @RequestMapping(value="/index.do", method = RequestMethod.GET)
    protected ModelAndView Submit(HttpServletRequest request, HttpServletResponse response) throws Exception 

        // TODO Auto-generated method stubs
        System.out.println(" Inside the controller ");

</beans>

还有我的 serviceImpl 类:

    @Service("MyService")
public class MyServiceImpl implements MyService

@Autowired
MyDAO myDAO;

还有我的 DaoImpl 类:

   @Repository/*("myDAO")*/
   public class MyDAOImpl implements MyDAO

List<String> clientList;

 @Autowired
 private SessionFactory sessionFactory;

 private Session session;

 private Session currentSession() 
        return this.sessionFactory.getCurrentSession();
    

@Override
public List<ClientInfoBean> getClientList(String currentQrt) throws DataStoreException 
    // TODO Auto-generated method stub
    return (List<ClientInfoBean>) this.currentSession().
    createCriteria("Select * from myTable);

它仍然给出以下例外。

org.springframework.beans.factory.BeanCreationException:创建名为“MyController”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.xxx.service.MyService com.xxx.controller.MyController.MyService;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为 [com.xxx.service.MyService] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1116) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458) 在 org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)

原因:org.springframework.beans.factory.BeanCreationException:无法自动装配字段:private com.xxx.service.MyService com.xxx.controller.MyController.MyService;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为 [com.xxx.service.MyService] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514) 在 org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285) ... 97 更多

原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为 [com.xxx.service.MyService] 的合格 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:@org.springframework.beans.factory.annotation.Autowired(required=true) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:988) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:858) 在 org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:770) 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486) ... 99 更多

【问题讨论】:

你可以为此制作一个父包吗?:&lt;context:component-scan base-package="com.xxx" /&gt; 是的,也试过了。仍然给出与下面粘贴的相同的错误。 :( 您对服务和 daos 的定义与实现在同一个包中? Impl 在不同的包中,定义在不同的包中:com.service 和 com.serviceImpl com.serviceImplcom.service.impl? 【参考方案1】:

所以问题出在你的包裹上:

您在:com.xxx.servicecom.xxx.dao 中有服务和 daos 的定义

以及您的实现:com.xxx.serviceImplcom.xxx.daoImpl

也加入&lt;context:component-scan base-package="com.xxx.serviceImpl,com.xxx.daoImpl"/&gt;

您面临的下一个问题是事务管理:

你还没有在 spring 配置中定义它。这是如何执行此操作的示例:

<!-- Hibernate 3 Annotation SessionFactory Bean definition-->
<bean id="sessionFactory"
      class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
            <prop key="hibernate.show_sql">false</prop>
            <prop key="hibernate.jdbc.batch_size">$batchSize</prop>
        </props>
    </property>
</bean>
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

在此之后,您需要将一个方法或您的服务实现标记为@Transactional,以便让 spring 处理这个。

【讨论】:

如果您对此答案满意。标记为已回答。【参考方案2】:

异常清楚的告诉你bean没有配置 NoSuchBeanDefinitionException:没有 [com.xxx.service.MyService] 类型的限定 bean

您能否检查您在注释中给出的 bean 名称是否与参数名称匹配。我的服务与我的服务。

另外添加一个 setter 可能是个好主意,因为 spring 可以调用 setter 来注入依赖项,而不是使用反射来注入它。

【讨论】:

你能分享一个通过setter注解和注入的例子吗? 我们是否必须在 spring xml 中添加这些: 你要么需要基于注解的配置,要么需要基于 xml 的配置,两者都不是同时需要的。这是一个简单的例子mkyong.com/spring/…【参考方案3】:

当你定义 @Service("MyService") public class MyServiceImpl implements MyService 要么 @Repository("MyDAO") public class MyDAOImpl implements MyDAO 您实际上是在告诉 spring 创建名称为“MyService”和“MyDAO”的 bean

当你定义喜欢 @Autowired private MyService myService; @Autowired private MyDAO myDAO; 您从春天开始要求提供名称为“myService”和“myDAO”的bean。

由于 spring 创建的 bean 的名称与您所要求的不同,因此它给出了错误。 您必须在 @Service 和 @Repository 注释中保持 bean 的名称与接口的变量名称相同。

@Service("myService")
public class MyServiceImpl implements MyService


private MyService myService;

【讨论】:

我按照你的说法进行了更改,但仍然出现异常:org.springframework.beans.factory.BeanCreationException:创建名称为“myController”的bean时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.xxx.service.MyService com.xxx.controller.MyController.MyService;嵌套异常是 org.springframework.beans.factory.CannotLoadBeanClassException:找不到类 [com.xxx.dao.MyDAOImpl] 用于 ServletContext 资源中定义的名称为“MyDAO”的 bean 你能给我看一下MyDAOImpl.java文件的全部代码吗 有什么遗漏吗? 现在说找不到MyDAO。您应该将 MyDAOImpl 更改为 @Repository("myDao")【参考方案4】:

当您将服务限定为“MyService”时,您可以添加如下限定符来查找它。默认情况下 spring 应该按 type 自动装配,所以组件扫描应该加载你的服务。如果您在 xml 中部分定义 bean 并期望自动装配其他服务,则必须添加 spring-servlet.xml

@Autowired
  @Qualifier("MyService")
    private MyService myService;

还将您的控制器类更改为 MyController 而不是 myController。 并且删除构造函数myController(),spring 会为你构造控制器bean。尝试删除所有spring bean类中的所有构造函数,spring会为你构造。一开始你可以避免限定bean,删除括号中的名称(“MyService”,“MyDao”等......)

【讨论】:

你的意思是说我在servlet.xml中添加了定义? 如您所愿,您可以在 servlet.xml 中完全或部分定义 bean 或不定义任何内容。如果您没有在 xml 中定义 beans 并使用 autowired 之类的注释,则必须通过 、 以及 web.xml 中的 ContextLoaderListener 告诉 spring 启用注释(如果您有任何其他上下文)听众。并且您必须使用正确的 bean 命名,就像在您的示例中您提到的服务名称为 "MyService" ,所以您需要像上面那样在自动装配中进行限定。 我在 web.xml 中添加了这个:org.springframework.web.context.ContextLoaderListener 好的,为什么你的控制器类名是小写的,试着把它改成大写 public class MyController ,可能就是没有找到的原因。 看我上面的回答,把控制器类名改成MyController,去掉构造函数myController()【参考方案5】:

使用

@Service
public class MyServiceImpl implements MyService

代替

@Service("MyService")
public class MyServiceImpl implements MyService

【讨论】:

以上是关于具有休眠 CRUD 操作的 Spring 3 注释:@Autowired 未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC“org.hibernate.PropertyAccessException”中的休眠注释映射异常

使用 MySQL 和 Oracle 进行休眠自动密钥生成

带有注释和(动态)AbstractRoutingDataSource 的 Spring 3.1.3 + Hibernate 配置

具有多租户休眠的 Spring-Data JPA

字节 [] 的正确休眠注释

spring jdbcTemplate的CRUD操作