当我尝试将存储库注入控制器类时,为什么我会获得此运行时错误?

时间:2015-01-08 09:10:36

标签: java spring spring-mvc annotations autowired

我发现使用 @Autowired 注释将一个存储库类(实现DAO)的实例注入另一个类时会遇到一些问题。

所以我的仓库类名为 KMProjectInfoServiceImpl

@Repository("kmProjectInfoService")
public class KMProjectInfoServiceImpl extends AbstractService implements KMProjectInfoService {


    public List<KM_ProjectInfo> getProjectInfoList() {
        return getHibernateTemplate().execute(
                new HibernateCallback<List<KM_ProjectInfo>>() {
                    public List<KM_ProjectInfo> doInHibernate(Session session) throws HibernateException, SQLException {
                        return getProjectsInformationsList(session);
                    }
                }
        );
    }

    public List<KM_ProjectInfo> getProjectInfoListByFolderTech() {
        return getHibernateTemplate().execute(
                new HibernateCallback<List<KM_ProjectInfo>>() {
                    public List<KM_ProjectInfo> doInHibernate(Session session) throws HibernateException, SQLException {
                        return getProjectsInformationsListByFolderTech(session);
                    }
                }
        );
    }

    public KM_ProjectInfo getProjectInfobyId(long idProjectInfo) {
        final Long id = idProjectInfo;
        return getHibernateTemplate().execute(
                new HibernateCallback<KM_ProjectInfo>() {
                    public KM_ProjectInfo doInHibernate(Session session) throws HibernateException, SQLException {
                        return getProjectInfo(id, session);
                    }
                }
        );
    }

    public void save(KM_ProjectInfo projectInfo) {
        // L'oggetto non è già presente sulla tabella
        if(projectInfo.getIdProjectInfo() == null){
            getHibernateTemplate().persist(projectInfo);    // lo rende persistente
        }
        // L'oggetto è già presente sulla tabella
        else {
            getHibernateTemplate().merge(projectInfo);      // fa l'update
        }
    }


    private List<KM_ProjectInfo> getProjectsInformationsList(Session session) {
        // Create query:
        Query query = session.getNamedQuery("kmProjectInfoList");
        List<KM_ProjectInfo> projectInfoList =  query.list();
        return projectInfoList;
    }

    private List<KM_ProjectInfo> getProjectsInformationsListByFolderTech(Session session) {
        // Create query:
        Query query = session.getNamedQuery("kmProjectInfoByFolderTech");
        List<KM_ProjectInfo> projectInfoList =  query.list();
        return projectInfoList;
    }

    private KM_ProjectInfo getProjectInfo(Long id, Session session) {
        // Create query:
        Query query = session.getNamedQuery("kmProjectInfoById");
        query.setParameter("projectInfoId", id);
        KM_ProjectInfo projectInfo = (KM_ProjectInfo) query.uniqueResult();
        return projectInfo;
    }
}

正如您所看到的,这个类使用 @Repository 注释进行注释,以此方式将 kmProjectInfoService 名称提供给我的存储库:

@Repository("kmProjectInfoService")

所以现在我必须将此存储库注入名为 ConfigurationProjectAction 的控制器类中,该控制器类必须将其用作依赖项。

所以我有这样的事情:

@Controller("confProjectActionController")
@Scope("prototype")
public class ConfigurationProjectAction extends KMAction implements PortletPreferencesAware {

    @Autowired
    @Qualifier("kmProjectInfoService")
    private KMProjectInfoServiceImpl

    ................................................
    ................................................
    ................................................
    ................................................
}

正如您在上一个代码段中所看到的,我尝试使用 @Autowired 注释将指定名称的存储库注入 kmProjectInfoService (使用 @Qualifier 注释)。

我的IDE没有标记错误,我没有编译时间错误但是当我尝试执行我的应用程序时,我在stacktrace中获取以下错误消息:

2015-01-08 10:07:29,321 [[ACTIVE] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'] ERROR commons.CommonsLogger.error(38) - Could not execute action
Unable to instantiate Action, confProjectActionController,  defined for 'startConfigurationProjectAction' in namespace '/configProject'Error creating bean with name 'confProjectActionController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private egp.prc.km.services.KMProjectInfoServiceImpl egp.prc.km.actions.configurationProject.ConfigurationProjectAction.kmProjectInfoServiceRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [egp.prc.km.services.KMProjectInfoServiceImpl] 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), @org.springframework.beans.factory.annotation.Qualifier(value=kmProjectInfoService)}
    at com.opensymphony.xwork2.DefaultActionInvocation.createAction(DefaultActionInvocation.java:318)
    at com.opensymphony.xwork2.DefaultActionInvocation.init(DefaultActionInvocation.java:399)
    at com.opensymphony.xwork2.DefaultActionProxy.prepare(DefaultActionProxy.java:198)

    ..........................................................................
    ..........................................................................
    ..........................................................................
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private egp.prc.km.services.KMProjectInfoServiceImpl egp.prc.km.actions.configurationProject.ConfigurationProjectAction.kmProjectInfoServiceRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [egp.prc.km.services.KMProjectInfoServiceImpl] 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), @org.springframework.beans.factory.annotation.Qualifier(value=kmProjectInfoService)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)

    ..........................................................................
    ..........................................................................
    ..........................................................................

为什么呢?可能是导致此错误的原因是什么?我错过了什么?我怎样才能尝试修复它并将我的存储库注入我的控制器类?

2 个答案:

答案 0 :(得分:0)

尝试注入不是KMProjectInfoService接口的实现,而是直接接口。另外,我建议删除注释级别的存储库名称:

@Repository("kmProjectInfoService")

而不是使用@Repository

在此之后,您的界面可用于注入,因为它不与存储库实现的名称重叠。

Spring使用代理模式进行注入。因此,您需要注入接口。

答案 1 :(得分:0)

@Autowired wires byType默认。因此,如果弹簧容器中只有一个匹配的bean,则无需使用@Qualifier。试试以下。

@Autowired
//@Qualifier("kmProjectInfoService")
private KMProjectInfoService kmProjectInfoService;