• springboot 反射调用ServiceImpl,报错:java.lang.NullPointerException,mapper为null


    springboot 使用反射调用ServiceImpl,报错:java.lang.NullPointerException

     是由于ServiceImpl的mapper为null导致的,以下为原实现代码:

    1. // 包名+类名
    2. Class classzz = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
    3. // 获取构造器对象
    4. Constructor constructor = null;
    5. try {
    6. constructor = classzz.getConstructor();
    7. } catch (NoSuchMethodException e) {
    8. e.printStackTrace();
    9. }
    10. // 利用构造器对象创建一个对象
    11. Object o = constructor.newInstance();
    12. // 传递需要执行的方法 传递参数类型,如果没有可以不用填写
    13. Method method = classzz.getMethod("方法名称", long.class,String.class,String.class );
    14. // invoke 方法,并传递参数,如果没有参数,可以不用填写
    15. Object obj =method.invoke(o, 5,
    16. "param1",
    17. "param2");

    后查询方式,需要先ContextLoader.getCurrentWebApplicationContext(),但是还没有走到invoke,获取的ContextLoader.getCurrentWebApplicationContext()就为null。

    最终解决实现的方式如下:

    1.新建类 SpringBootBeanUtil

    1. package com.smart.hyd.common.utils.reflect;
    2. import org.springframework.beans.BeansException;
    3. import org.springframework.context.ApplicationContext;
    4. import org.springframework.context.ApplicationContextAware;
    5. import org.springframework.stereotype.Component;
    6. /**
    7. * SpringBoot 普通类获取Spring容器中的bean工具类
    8. */
    9. @Component
    10. public class SpringBootBeanUtil implements ApplicationContextAware {
    11. private static ApplicationContext applicationContext;
    12. public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    13. if (SpringBootBeanUtil.applicationContext == null) {
    14. SpringBootBeanUtil.applicationContext = applicationContext;
    15. }
    16. System.out.println("========ApplicationContext配置成功========");
    17. // System.out.println("========在普通类可以通过调用SpringBootBeanUtil.getApplicationContext()获取applicationContext对象========");
    18. System.out.println("========applicationContext="+ SpringBootBeanUtil.applicationContext +"========");
    19. }
    20. /**
    21. * 获取applicationContext
    22. * @return
    23. */
    24. public static ApplicationContext getApplicationContext() {
    25. return applicationContext;
    26. }
    27. /**
    28. * 通过name获取 Bean.
    29. * @param name
    30. * @return
    31. */
    32. public static Object getBean(String name) {
    33. return getApplicationContext().getBean(name);
    34. }
    35. /**
    36. * 通过class获取Bean.
    37. * @param clazz
    38. * @return
    39. */
    40. public static T getBean(Class clazz) {
    41. return getApplicationContext().getBean(clazz);
    42. }
    43. /**
    44. * 通过name,以及Clazz返回指定的Bean
    45. * @param name
    46. * @param clazz
    47. * @return
    48. */
    49. public static T getBean(String name, Class clazz) {
    50. return getApplicationContext().getBean(name, clazz);
    51. }
    52. }

    2.调用SpringBootBeanUtil.getApplicationContext(),在invoke的时候,第一个参数applicationContext.getBean(ServiceImplType),具体实现参照下面代码。

    1. try {
    2. //从ApplicationContext中取出已创建好的的对象
    3. //不可直接反射创建serviceimpi对象,因为反射创建出来的对象无法实例化dao接口
    4. ApplicationContext applicationContext = SpringBootBeanUtil.getApplicationContext();
    5. //反射创建serviceimpi实体对象,和实体类
    6. Class ServiceImplType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
    7. // Class entityType = Class.forName("com.XXX.XXX.service.impl.SenDataServiceImpl");
    8. //反射设置方法参数。
    9. Method method = ServiceImplType.getDeclaredMethod("方法名称",long.class,String.class,String.class );
    10. //在ApplicationContext中根据class取出已实例化的bean
    11. method.invoke(applicationContext.getBean(ServiceImplType), 5,
    12. "param1",
    13. "param2");
    14. } catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
    15. e.printStackTrace();
    16. LOGGER.error("\n onMessage接收处理消息失败 - {}", "方法名称");
    17. }

    这样就解决了反射调用ServiceImpl,mapper为null报错的问题。

    参照解决方法的地址:

    springboot中 利用java反射调用Service,注入Dao接口为null - 水狼一族 - 博客园

  • 相关阅读:
    SpringMVC(一、快速入门)
    金仓数据库 KingbaseGIS 使用手册(4. 数据管理和查询)
    Redis源码与设计剖析 -- 18.Redis网络连接库分析
    用友U8 crm客户关系管理存在任意文件上传漏洞2 附POC
    SqlServerAgent当前未运行,因此无法将此操作通知他。错误:22022
    (Python入门)函数
    FLUME 安装配置及使用示例
    dns隧道的通信原理及特征
    stl_stack_queue的模拟实现
    如何在 Windows 10 上启用和设置 BitLocker 加密
  • 原文地址:https://blog.csdn.net/ying456baby/article/details/126161176