【问题标题】:Why doesn't the spring @Autowired work with java generics为什么 spring @Autowired 不能与 java 泛型一起使用
【发布时间】:2012-06-01 23:25:48
【问题描述】:

受 spring data awesomeness 的启发,我想创建一个抽象的 RESTController,我可以为我的很多控制器扩展它。我创建了以下类:

@Controller
public abstract class RESTController<E, PK extends Serializable, R extends PagingAndSortingRepository<E, PK>>
{
    @Autowired
    private R repository;

    @RequestMapping(method=RequestMethod.GET, params={"id"})
    @ResponseBody 
    public E getEntity(@RequestParam PK id)
    {
        return repository.findOne(id);
    }

    ...
}

我希望泛型允许我在存储库中使用@Autowired,但我收到以下错误:

SEVERE: Allocate exception for servlet appServlet
org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.data.repository.PagingAndSortingRepository] is defined: expected single matching bean but found 3: [groupRepository, externalCourseRepository, managedCourseRepository]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    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)

我明白错误告诉我什么,@Autowired 有不止一个匹配项。我很困惑,因为我认为通过创建以下控制器会起作用:

@Controller
@RequestMapping(value="/managedCourse")
public class ManagedCourseController extends RESTController<ManagedCourse, Long, ManagedCourseRepository>
{
    ...
}

这很容易通过在 RESTController 中使用这样的方法来解决:

protected abstract R getRepository();

然后在你的实现类中这样做:

@Autowired
private ManagedCourseRepository repository;

@Override
protected ManagedCourseRepository getRepository() 
{
    return repository;
}

我只是想知道是否有人对我如何使它起作用有任何想法。

我还发现了this 有趣的文章。

【问题讨论】:

  • 我不确定它是否会起作用,但请尝试使用Qualifier 注释以及Autowired
  • 如果我遗漏了什么,请原谅我,但是当抽象类不知道它的实现类时,它会如何帮助它。感谢您的回复。请解释一下。

标签: java spring generics spring-mvc autowired


【解决方案1】:

在这种情况下,我实际上会推荐基于 XML 的注释连接。在我看来,您正试图避免控制器实例中出现大量不必要的重复。如果您有一个 REST 控制器类,则容器可以根据需要实例化任意数量的实例,将每个实例映射到不同的 URI。

注解更像是您计划创建单个实例的情况的简写。这恰好涵盖了大约 90% 的基于表单的 J2EE 会话 bean,但它不是灵丹妙药。

【讨论】:

    【解决方案2】:

    我认为没有任何方法可以使用 Spring 进行这项工作。 之前看过Spring Ioc的源码,发现它不关心Class Level上的Generic Declaration,只关心Field或Method Parameter。有兴趣的可以看一下org.springframework.beans.factory.config.DependencyDescriptor类,你会发现我说的。

    【讨论】:

      【解决方案3】:

      Spring 使用成员的类型来“自动连接”它,因此使用泛型您只提供泛型类型信息,而不是您希望 spring 为您注入的特定类型。

      【讨论】:

        猜你喜欢
        • 2016-02-28
        • 2016-02-23
        • 1970-01-01
        • 2014-04-24
        • 2023-01-30
        • 1970-01-01
        • 1970-01-01
        • 2021-12-09
        • 1970-01-01
        相关资源
        最近更新 更多