SpringBoot在自定义实现类中调用service层等Spring其他层报错为null的解决办法

简介: SpringBoot在自定义实现类中调用service层等Spring其他层报错为null的解决办法

背景:

使用Springboot整合Netty写了一个TCP实现客户端服务端通信接收主板信息,然后需要将设备实时发送的检测数据等关键信息存储到数据库,也是为了能最快利用mybatis框架实现数据访问,然后在TCP服务器消息处理时,需要写数据库,直接调用DAO层,编译报错。改为调用Service层,编译正常,运行到调用的地方,报空指针异常,跟踪到异常位置,发现service为空,也就是按照之前controller层通过

@Autowired注入service层失效。

解决方案:

1.不要用mybatis,使用原生的jdbc连接数据库进行存储

代码如下:

blic class MessageHandler extends ChannelInboundHandlerAdapter {
  private static Logger logger = LoggerFactory.getLogger(MessageHandler.class);
  /**
   * 本方法用于读取客户端发送的信息
   * @param ctx
   * @param msg
   * @throws Exception
   */
  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    System.out.println("输出接收过来的信息: "+msg);
        //将msg进行入库操作
        //基础的jdbc连接操作,这里省去基础的连接方法
        String str;
        // 传递sql语句
        Statement stt;
        Connection conn = null;
        String sql = "insert into test_db(datas) values ('"+msg+"')";  //写SQL
        try {
            conn = mysqlimages.getConn();  //一个连接数据库的方法,这就不贴了,很简单的
            //获取Statement对象
            stt = conn.createStatement();
            //执行sql语句
            stt.executeUpdate(sql);
            logger.info(">>>插入数据库成功");
            str = Const.SECCESS;
        }catch (Exception e) {
            logger.error("<<<插入数据错误--"+e.getMessage());
            str = Const.ERROR;
        }

这种方法可以实现,但是不推荐,本来这里数据量就大,再用jdbc没有连接池将会造成业务阻塞netty本身的worker工作线程。

所以推荐使用下一种方法:

2.使用@PostConstruct静态初始化spring的成员变量

代码如下:

channelRead方法:

  //调用线程池处理大数据量问题
  ExecutorService executor = Executors.newFixedThreadPool(5);
    int num=0;
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.out.println();
        log.info("加载客户端报文......");
        log.info("【" + ctx.channel().id() + "】" + " :" + msg);
        /**
         *  下面可以解析数据,保存数据,生成返回报文,将需要返回报文写入write函数
         */
        num++;
        System.out.println(num);//输出当前已经接收过来的条数
        //引入异步业务线程池的方式,避免长时间业务耗时业务阻塞netty本身的worker工作线程
        executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                log.info("收到服务端发来的方法请求了--------------------------------------------");
                ServerHandler handler = new ServerHandler();//这个类在下面
                handler.test(msg.toString());
                return null;
            }
        });
        //响应客户端
        this.channelWrite(ctx.channel().id(), msg);
    }
@Component 
public class ServerHandler extends IoHandlerAdapter {
    @Autowired
    private ITest2StaticService test2StaticService;// 注入service方法
    private static ServerHandler serverHandler;
    @PostConstruct //通过@PostConstruct实现初始化bean之前进行的操作
    //在初始化的时候初始化静态对象和它的静态成员变量healthDataService,原理是拿到service层bean对象,静态存储下来,防止被释放。
    public void init() {
        serverHandler = this;
        serverHandler.test2StaticService = this.test2StaticService;
        // 初使化时将已静态化的testService实例化
    }
    //测试调用
    public void test(String msg) {
        Test2Static test2Static = new Test2Static();
        test2Static.setBb(Double.valueOf(msg));
        test2Static.setCreateTime(LocalDateTime.now());
        System.out.println("1111111111111111");
        boolean b = serverHandler.test2StaticService.save(test2Static);
        System.out.println("---! "+b);
    }
}
IoHandlerAdapter类 所用到的maven坐标:
  <!-- https://mvnrepository.com/artifact/org.apache.mina/mina-core -->
        <dependency>
            <groupId>org.apache.mina</groupId>
            <artifactId>mina-core</artifactId>
            <version>2.1.3</version>
        </dependency>

2.说明:

将需要调用Spring的Service层的类通过@Component注解为组件加载;

同样通过@Autowired获取Service层的Bean对象;

为类声明一个静态变量,方便下一步存储bean对象;

划重点:通过注解@PostConstruct ,在初始化的时候初始化静态对象和它的静态成员变量healthDataService,原理是拿到service层bean对象,静态存储下来,防止被释放。


找了好久,终于找到这个方法,本来以为很简单,却总是怎么也写不进去数据库。调用service一直为空,可困扰我好久。

特此记录。。。。。。。。。。。。。。。。。


*那些浪费的时间,都是丢在真理路上的金子~~~~!*

目录
相关文章
|
1月前
|
监控 Java 应用服务中间件
Spring和Spring Boot的区别
Spring和Spring Boot的主要区别,包括项目配置、开发模式、项目依赖、内嵌服务器和监控管理等方面,强调Spring Boot基于Spring框架,通过约定优于配置、自动配置和快速启动器等特性,简化了Spring应用的开发和部署过程。
52 19
|
1月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
57 2
|
1月前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
90 1
|
1月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
26 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
1月前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
24 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
1月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
168 2
|
1月前
|
前端开发 安全 Java
【Spring】Spring Boot项目创建和目录介绍
【Spring】Spring Boot项目创建和目录介绍
84 2
|
1月前
|
Java Spring 容器
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
这篇文章讨论了在Spring Boot 3.2.1版本中,同名同类型的bean和@Service注解类之间冲突的问题得到了解决,之前版本中同名bean会相互覆盖,但不会在启动时报错,而在配置文件中设置`spring.main.allow-bean-definition-overriding=true`可以解决这个问题。
85 0
Springboot3.2.1搞定了类Service和bean注解同名同类型问题修复
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
112 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
1月前
|
Java Spring
springboot 学习十一:Spring Boot 优雅的集成 Lombok
这篇文章是关于如何在Spring Boot项目中集成Lombok,以简化JavaBean的编写,避免冗余代码,并提供了相关的配置步骤和常用注解的介绍。
91 0