我正在尝试从应用程序上下文中提取bean。
所以我定义了类:
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public void setApplicationContext(ApplicationContext _applicationContext) throws BeansException {
applicationContext = _applicationContext;
}
}在我的applicationContext.xml里
<bean id="workflowService" class="com.mycompany.util.WorkflowService">
<bean id="applicationContextProvider" class="com.mycompany.util.ApplicationContextProvider"></bean>
<context:annotation-config />但是,在我的代码中,当我尝试:
WorkflowService service = (WorkflowService) ApplicationContextProvider.getApplicationContext().getBean("workflowService");我得到:
java.lang.ClassCastException:不能将$Proxy40转换为com.mycompany.util.WorkflowService
编辑的:
WorkflowService代码:
public class WorkflowService implements Serializable {
...
@PostConstruct
public void init() {
}
...
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public Collection<lData> findData(Integer contractId) {
}
}发布于 2011-03-07 20:57:04
我猜WorkflowService是一个实现至少一个接口的类(您没有提供足够的代码)。您正在尝试从Spring中查找确切的类,而您应该请求其中一个接口。
这是因为Spring大部分时间都将bean封装在几个代理(例如事务性代理)中。如果类实现至少一个接口,则生成的代理实现所有接口,但不能转换为原始类。如果类没有实现任何接口(对于重量级服务来说通常被认为是一种不好的实践,但值得怀疑),Spring将使用来自原始类的CGLIB子类。在这种情况下,代码将是有效的。
发布于 2011-03-07 22:00:41
你的问题是:
WorkflowService implements SerializableSpring生成的任何代理都将实现类所做的所有接口--在本例中是Serializable,这几乎肯定不是您想要的。
您应该做的是从WorkflowService中提取一个新的接口,其中包括findData方法(让我们称之为WorkflowOperations)。通过实现该接口,您将能够对该接口进行强制转换。
public interface WorkflowOperations {
Collection<lData> findData(Integer contractId);
}
public class WorkflowService implements WorkflowOperations {
...
@PostConstruct
public void init() {
}
...
@Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
public Collection<lData> findData(Integer contractId) {
}
}然后:
WorkflowOperations service = (WorkflowOperations) ApplicationContextProvider.getApplicationContext().getBean("workflowService");您可能还应该从Serializable中删除WorkflowService。您几乎肯定不需要这个,像这样序列化Spring是没有意义的。如果您只是根据习惯添加了Serializable,那么就删除它(并摆脱这个特定的习惯)。
发布于 2011-03-07 22:53:18
您正在用@Transactional注释您的服务,所以Spring使用事务性JDK动态代理包装您的服务bean,该代理实现与您的bean相同的接口,但不是WorkflowService。这就是当您尝试将ClassCastException赋值给WorkflowService变量时得到它的原因。我认为有两种可能的解决办法:
WorkflowService,并在WorkflowServiceImpl类中实现它。然后,在Spring上下文中,将bean定义从WorkflowService更改为WorkflowServiceImpl。这是我推荐的,既作为一般设计原则,也特别是在Spring环境中工作: Spring喜欢interfaces.<tx:annotation-driven/>元素中添加proxy-target-class="true",以便通过子类强制Spring实现代理,从而使proxy instanceof WorkFlowService成为真。我觉得这个解决方案更脏。还请注意,您以这种方式添加了CGLIB的依赖项。。
https://stackoverflow.com/questions/5225104
复制相似问题