Spring 4.0.0中的Spring JDBC模板java.lang.ClassCastException

时间:2013-10-08 20:55:04

标签: java spring jdbctemplate spring-jdbc

我是斯普林斯的新手。我正在尝试运行JDBCTempalte示例。我得到了ClassCastException。这对我没有意义。

我的上下文文件

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- I have removed my config, I have tried JDBC code it is working with this datasource-->
</bean>

<bean id="jdbcDAO" class="com.sarma.spring.jdbcEx.JDBCDAOImpl">
<property name="dataSource" ref="dataSource"/><!-- This is my jdbc example it is working-->
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

我的主要课程

try{
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
org.springframework.jdbc.core.JdbcTemplate jdbc = (org.springframework.jdbc.core.JdbcTemplate)context.getBean("jdbcTemplate");
String query = "SELECT ACNT_NBR FROM eit.ACNT WHERE ACNT_ID=13057";
int o= jdbc.queryForInt(query);
}catch(Exception e){
    e.printStackTrace();
}

输出

2013-10-08 16:43:34 INFO  ClassPathXmlApplicationContext:513 - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1c672d0: startup date [Tue Oct 08 16:43:34 EDT 2013]; root of context hierarchy
2013-10-08 16:43:34 INFO  XmlBeanDefinitionReader:316 - Loading XML bean definitions from class path resource [applicationContext.xml]
2013-10-08 16:43:34 INFO  DriverManagerDataSource:133 - Loaded JDBC driver: oracle.jdbc.driver.OracleDriver
java.lang.ClassCastException: $Proxy12 cannot be cast to org.springframework.jdbc.core.JdbcTemplate
    at com.sarma.spring.jdbcEx.main.JdbcExMain.main(JdbcExMain.java:45)

我的45行是

org.springframework.jdbc.core.JdbcTemplate jdbc = (org.springframework.jdbc.core.JdbcTemplate)context.getBean("jdbcTemplate");

我犯了什么错吗?谢谢你的帮助

谢谢,

CVSR Sarma

1 个答案:

答案 0 :(得分:3)

除非需要应用某些特殊的外部行为,否则通常不会代理Spring bean。例如,AOP advicetransaction managementbean scope

您的背景似乎不完整。如果您声明了一些与JdbcTemplate方法匹配的AOP连接点,那么该bean将被代理。您可以指定代理设置for example if Spring should proxy-target-class instead of the interface。如果你的类路径上有CGLIB库,那么设置

就不会有任何问题
<aop:config proxy-target-class="true"> ...

JDK代理的一个小例子

public static void main(String[] args) throws Exception {
    JdbcTemplate template = new JdbcTemplate();
    Object proxy = Proxy.newProxyInstance(template.getClass().getClassLoader(), template.getClass().getInterfaces(), new ProxyJdbcTemplateHandler(template));
    System.out.println(proxy.getClass());
    System.out.println(proxy.getClass().getSuperclass());
    System.out.println(Arrays.toString(proxy.getClass().getInterfaces()));
}

public static class ProxyJdbcTemplateHandler implements InvocationHandler {
    private JdbcTemplate target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // do something with target
        return null;
    }

    public ProxyJdbcTemplateHandler(JdbcTemplate target) {
        this.target = target;
    }
}

打印

class $Proxy0
class java.lang.reflect.Proxy
[interface org.springframework.jdbc.core.JdbcOperations]

代理具有JdbcTemplate的超接口类型,但不是类型本身。它的父类实际上是Proxy。为此,您需要使用CGLIB代理,方法是在类路径上提供CGLIB jar并在配置中指定proxy-target-class="true"