当前位置: 首页 > 知识库问答 >
问题:

如何自动关联泛型类型

狄宇
2023-03-14

我是Spring的新手,我正在尝试自动连接一个通用DAO。不幸的是,我遇到了一个错误。我试图根据它搜索信息,但大多数解决方案都声明使用@Qualifier注释,我认为这与我想要实现的目标背道而驰。

所以下面的一些代码(我将摆脱类参数,一旦我处理当前问题):

public interface GenericDAO<T> {

    T save(T entity, Class<T> tClass);
    List<T> findAll(Class<T> tClass);
    List<T> findAllByKeyword(String keyword, Class<T> tClass);
    T findById(int id, Class<T> tClass);
    void deleteById(int id, Class<T> tClass);

}

public class GenericDAOImpl<T> implements GenericDAO<T> {

    SessionFactory sessionFactory;


    public GenericDAOImpl(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    @Transactional
    public T save(T entity, Class<T> tClass) {
        //body
    }

    //other methods
}

@Repository
public class FooDAOImpl extends GenericDAOImpl<Foo> {

    @Autowired
    public FooDAOImpl(SessionFactory sessionFactory) {
        super(sessionFactory);
    }

服务

public interface GenericService<T> {

    T save(T entity, Class<T> tClass);
    List<T> findAll(Class<T> tClass);
    List<T> findAllByKeyword(String keyword, Class<T> tClass);
    T findById(int id, Class<T> tClass);
    void deleteById(int id, Class<T> tClass);

}

public class GenericServiceImpl<T, T_DAO extends GenericDAO<T>> implements GenericService<T> {


    private final T_DAO dao;

    public GenericServiceImpl(T_DAO dao) {
        this.dao = dao;
    }

    @Override
    public T save(T entity, Class<T> tClass) {
        return dao.save(entity, tClass);
    }

    // other methods
}

@Service
public class FooServiceImpl extends GenericServiceImpl<Foo, FooDAOImpl> {

    @Autowired
    public FooServiceImpl(FooDAOImpl fooDAOImpl) {
        super(fooDAOImpl);
    }
}
}

和下面抛出的错误:

javax.servlet.ServletException: Servlet.init() for servlet [dispatcher] threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.base/java.lang.Thread.run(Thread.java:834)
Root Cause

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'fooServiceImpl' defined in class path resource [*/*/*/service/FooServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooDAOImpl' is expected to be of type '*.*.*.repository.FooDAOImpl' but was actually of type 'com.sun.proxy.$Proxy76'
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:797)
    org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.base/java.lang.Thread.run(Thread.java:834)
Root Cause

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'fooDAOImpl' is expected to be of type '*.*.*.repository.FooDAOImpl' but was actually of type 'com.sun.proxy.$Proxy76'
    org.springframework.beans.factory.support.DefaultListableBeanFactory.checkBeanNotOfRequiredType(DefaultListableBeanFactory.java:1736)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1713)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
    org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:884)
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:788)
    org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:227)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1356)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1203)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516)
    org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
    org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
    org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)
    org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)
    org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.base/java.lang.Thread.run(Thread.java:834)

共有1个答案

农诚
2023-03-14

错误是Spring未能创建beanCusterServiceImpl,因为CusterServiceImpl期望类型为CustomeDAOImpl的依赖项,并且Spring已注入com.sun.proxy.$Proxy76的依赖项。

Bean named 'customerDAOImpl' is expected to be of type 
'com.smartdigit.zalewski.repository.CustomerDAOImpl' but was actually of type 
'com.sun.proxy.$Proxy76'  

您必须更改FooServiceImpl类才能获得FooDAOInterface类型的依赖项,而不是它的实现。

比如:

public class FooServiceImpl extends GenericServiceImpl<> {
    @Autowired
    public FooServiceImpl(FooDAOInterface fooDAO) {
    super(fooDAOImpl);
   }
}

你必须传递一个接口类型foServiceImpl构造函数为了Spring自动装备它时,Spring上下文已初始化。

 类似资料:
  • 我在Spring 4.0(使用Spring Boot)环境中遇到以下情况: 映射界面: 映射实现: 服务: 我想做这样一个抽象的超类服务: 所以我可以有如下实现: 但是Spring告诉我它找不到EntityModelMapper的合格bean来注入服务类。这种情况是可能的,我做错了什么,还是我在挑战Spring依赖注入的极限? 堆栈跟踪:

  • “关联项”(associted items)是指一系列有关各种变量类型的 item(项) 的规则。它是 trait 泛型的扩展(extension),允许 trait 在内部定义新的项。 关联类型(associated type)就是这种项的其中一个。当 trait 在其容器类型(container type)上是泛型时,关联类型提供了更简单的使用模式。(原文:One such item is c

  • 这个问题是在泛型关联类型在Rust中可用之前提出的,尽管它们是被提出和开发的。 我的理解是,特征泛型和关联类型在它们可以绑定到结构的类型数量上有所不同。 关联类型仅绑定1个类型: 泛型关联类型是这两种类型的混合。它们绑定到一个类型,正好有一个关联的生成器,而生成器又可以关联任何数量的类型。那么前面示例中的和这个泛型关联类型有什么区别呢?

  • 可以自动绑定泛型类吗?考虑一下: 通用接口: 长子类型: 字符串子类型: 自定义模块:公共类CustomModule扩展AbstractModule{ } 主要的 是否可以以某种方式(例如:基抽象类、反射或其他)自动绑定

  • 使用“关联类型”可以增强代码的可读性,其方式是移动内部类型到一个 trait 作为output(输出)类型。这个 trait 的定义的语法如下: // `A` 和 `B` 在 trait 里面通过`type` 关键字来定义。 // (注意:此处的 `type` 不同于用作别名时的 `type`)。 trait Contains { type A; type B; // 通常

  • 关联类型 定义一个协议时, 有时在协议定义里声明一个或多个关联类型是很有用的. 关联类型给协议中用到的类型一个占位符名称. 直到采纳协议时, 才指定用于该关联类型的实际类型. 关联类型通过associatedtype关键字指定. 关联类型的应用 protocol Container { associatedtype ItemType mutating func append(_ i