Spring 4 - 自动装配泛型

4
我创建了一个通用接口CRUDService,可以生成多个实体服务类,并且所有服务类都实现相同的CRUD方法。
interface CRUDService<T> {

public abstract T saveEntity(T entity)

public abstract T getEntity(T entity)

public abstract long getCount()
}

然后我从我的实体Hypervisor中实现了一个服务类HypervisorService,该类实现了我的CRUDService。

@Service
class HypervisorService implements CRUDService<Hypervisor> {

@Autowired
private HypervisorRepository hypervisorRepository

@Override
@Transactional
public Hypervisor saveEntity(Hypervisor entity) {
    return hypervisorRepository.saveAndFlush(entity)
}

@Override
public Hypervisor getEntity(Hypervisor entity) {
    return hypervisorRepository.findOne(entity.getId())
}

@Override
public long getCount() {
    return hypervisorRepository.count()
}
}

但是当我尝试使用自动装配将其注入时,出现了问题。
@Autowired
private CRUDService<Hypervisor> hypervisorService

我遇到了一个"java.lang.ClassCastException: com.sun.proxy.$Proxy68无法转换为net.ifis.ites.hermes.services.HypervisorService"的异常。

我不明白为什么Spring会报出类转换异常,但当我将我的服务代码更改为

@Service
class HypervisorService<Hypervisor> implements CRUDService<Hypervisor> {
...
}

我的代码可以工作,我可以使用通用接口,但我认为这不是一个好的实践方式。

堆栈跟踪:

java.lang.ClassCastException: com.sun.proxy.$Proxy68 cannot be cast to net.ifis.ites.hermes.services.HypervisorService
at net.ifis.ites.hermes.services.HypervisorService$saveEntity.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:122)
at net.ifis.ites.hermes.ui.MyVaadinUI.init(MyVaadinUI.groovy:38)
at com.vaadin.ui.UI.doInit(UI.java:646)
at net.ifis.ites.hermes.ui.MyVaadinUI.doInit(MyVaadinUI.groovy)
at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:214)
at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:74)
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:350)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:721)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:466)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:358)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:318)
at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:128)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:146)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:50)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

在我的VaadinUI中,我只自动装配我的服务类,并生成一个超级管理程序,尝试将其保存到我的数据库中,并将所有超级管理程序的当前数据库计数可视化为标签。

@Component
@SpringUI
class MyVaadinUI extends UI {

@Autowired
private CRUDService<Hypervisor> hypervisorService

@Override
protected void init(VaadinRequest vaadinRequest) {

    VerticalLayout layout = new VerticalLayout()

    Hypervisor hypervisor = hypervisorService.saveEntity(new Hypervisor("KVM"))

    layout.addComponent(new Label("Hypervisors : " + hypervisorService.getCount()))

    setContent(layout)
}

}

我现在将尝试使用CGLIB来开发我的应用程序。


请发布完整的异常堆栈跟踪。 - JB Nizet
class HypervisorService<Hypervisor> implements CRUDService<Hypervisor> 并不是你想象中的那样。 - Sotirios Delimanolis
使用CGLIB代理,而不是JDK代理。 - Sotirios Delimanolis
异常似乎是从您自己的代码中抛出的。MyVaadinUI.init() 中有什么?您是否将自动装配的 hypervisorService 强制转换为 HypervisorService? - JB Nizet
1个回答

0

我在我的配置中使用

@EnableAspectJAutoProxy(proxyTargetClass=true) 现在我的代码可以正常工作了

class HypervisorService implements CRUDService<Hypervisor> {
...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接