Java动态代理,打印代理对象导致报错

    @Test
    public  void testApp1() {
        SqlSession sqlSession = SqlSessionFactory.openSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        //插入该行代码时会发生控制针异常报错
        //System.out.println(mapper);
        List allUsers = mapper.findAllUsers();
        for (User u : allUsers
                ) {
            System.out.println(u);
        }
    }

如图,打印该动态对象时,出现控制针异常报错。报错信息如下

java.lang.NullPointerException
	at cn.itheima.core.MapperProxyFactory.invoke(MapperProxyFactory.java:34)
	at com.sun.proxy.$Proxy4.toString(Unknown Source)
	at java.lang.String.valueOf(String.java:2994)
	at java.io.PrintStream.println(PrintStream.java:821)
	at cn.itheima.test.AppTest.testApp1(AppTest.java:48)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

搜索资料后发现,打印该动态对象时,会自动调用toString()方法,导致触发代理对象中的invoke方法。而在invoke方法中。

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodname = method.getName();
        String classname = method.getDeclaringClass().getName();
        //获得和配置文件的关联性
        Configuration configuration = new Configuration();
        //获得mapper封装相关内容
        Map mapperMap = configuration.getMapperMap();
        //获得数据库连接对象
        ComboPooledDataSource dataSource = configuration.getDataSource();
        System.out.println("===");
        System.out.println("数据源对象:"+ dataSource);
        Connection conn = dataSource.getConnection();
        Mapper mapper = mapperMap.get(classname + "." + methodname);
        String sql = mapper.getSqlString();
        System.out.println("sql语句"+sql);
        //处理resultSet
        List objects = Execute.selectList(mapper, conn);
        return objects;
    } 
  

由于method方法是toString,生成的key值无法在mapperMap找到对应的mapper对象,此时mapper为空,从而在下面的语句中发生了空指针异常报错

String sql = mapper.getSqlString();

 

你可能感兴趣的:(备忘)