具有休眠 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 更多
【问题讨论】:
你可以为此制作一个父包吗?:<context:component-scan base-package="com.xxx" />
是的,也试过了。仍然给出与下面粘贴的相同的错误。 :(
您对服务和 daos 的定义与实现在同一个包中?
Impl 在不同的包中,定义在不同的包中:com.service 和 com.serviceImpl
com.serviceImpl
或 com.service.impl
?
【参考方案1】:
所以问题出在你的包裹上:
您在:com.xxx.service
和 com.xxx.dao
中有服务和 daos 的定义
以及您的实现:com.xxx.serviceImpl
和 com.xxx.daoImpl
。
也加入<context:component-scan base-package="com.xxx.serviceImpl,com.xxx.daoImpl"/>
您面临的下一个问题是事务管理:
你还没有在 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 中添加这些:当你定义
@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 之类的注释,则必须通过使用
@Service
public class MyServiceImpl implements MyService
代替
@Service("MyService")
public class MyServiceImpl implements MyService
【讨论】:
以上是关于具有休眠 CRUD 操作的 Spring 3 注释:@Autowired 未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章
Spring MVC“org.hibernate.PropertyAccessException”中的休眠注释映射异常
带有注释和(动态)AbstractRoutingDataSource 的 Spring 3.1.3 + Hibernate 配置