gramyang
V2EX  ›  Java

Springboot 用 @Autowired 的坑

  •  
  •   gramyang · May 22, 2019 · 12224 views
    This topic created in 2733 days ago, the information mentioned may be changed or developed.
    我想很多老铁可能都碰到过,就是在 springboot 的非 controller 中使用 @Autowired 引发的空指针。

    我这里的 handler 报空指针:

    public class NettyHandler extends ChannelInboundHandlerAdapter {
    private ConcurrentHashMap<Long, Channel> channelMap;
    private Long key = System.currentTimeMillis();
    @Autowired
    private PlayerInfoHandler handler;

    查了一下,不少人都遇到过这样的问题,一个解决方法: https://blog.csdn.net/georgeshaw1/article/details/74943089

    代码:
    @Autowired
    protected HealthDataService healthDataService;
    private static ServerHandler serverHandler ;
    @PostConstruct //通过 @PostConstruct 实现初始化 bean 之前进行的操作
    public void init() {
    serverHandler = this;
    serverHandler.healthDataService = this.healthDataService;
    // 初使化时将已静态化的 testService 实例化
    }

    我这边试了一下不行啊。。。。咋搞呢??
    Supplement 1  ·  May 22, 2019
    刚刚修改了一下就好了,原因是 @Component 调用链中断,有一个环节使用了 new 而不是 @Autowired。
    37 replies  •  2019-05-26 14:16:39 +08:00
    Lonely
    Lonely
    May 22, 2019 via iPhone
    1
    你这 handler 有注册为 bean 吗?
    feiyuanqiu
    feiyuanqiu
    May 22, 2019 via Android
    2
    类上加个 @Component 或者 @Service 试试
    reeco
    reeco
    May 22, 2019
    3
    只有被 Spring 管理起来的 bean 才能使用注入,你这个类压根没被 Spring 管理,@Autowired 默认 required 是 true,注入是 null 直接启动失败了
    szq8014
    szq8014
    May 22, 2019 via Android
    4
    怀疑你不了解 Spring,handler 都没让 Spring 来管理怎么能注入成功?要么把 handler 交给 Spring 来管理,要么拿到 ApplicationContext 然后 getBean(HealthDataService.class) 这样拿到 HealthDataService 实例使用
    jwk345
    jwk345
    May 22, 2019 via iPhone
    5
    这不算坑
    npe
    npe
    May 22, 2019 via Android
    6
    Spring 容器里都没这个类,你能注入个啥?
    aragakiyuii
    aragakiyuii
    May 22, 2019 via Android
    7
    你找的这个不是说的挺清楚的嘛。。
    在你的 NettyHandler 类上加 @Component 或者 @Service,并且要保证你注入的 PlayerInfoHandler 这个类或者接口实现也交给 spring 管理了
    telami
    telami
    May 22, 2019❤️1
    8
    emmmm..
    gramyang
    gramyang
    OP
    May 22, 2019
    9
    @szq8014 确实 spring 用的不多
    NewDraw
    NewDraw
    May 22, 2019 via Android❤️2
    10
    哥们你太有意思了😄😄😄😄
    Umenezumi
    Umenezumi
    May 22, 2019
    11
    PlayerInfoHandler handler 你这个类没有被 spring 管理啊。。自动注入 required 默认是 true 自然报错
    trycatch
    trycatch
    May 22, 2019
    12
    最好用构造函数注入
    serical
    serical
    May 22, 2019 via Android
    13
    静态的通过 set 方法注入
    qwerthhusn
    qwerthhusn
    May 22, 2019
    14
    BTW,如果把 Handler 注册成 Bean,并且是单例的话,
    别忘了加上注解 @Shared,Netty 好像对 @Shared 有处理,标记为可重用的 Handler
    gramyang
    gramyang
    OP
    May 22, 2019
    15
    @qwerthhusn 基本上,netty 的业务 handler 是不会用到 @Sharable 的,所以我已经加上了
    gramyang
    gramyang
    OP
    May 22, 2019
    16
    @qwerthhusn 不对,我上一句话说的有语病。
    handler 我不想加上 @Sharable,因为不是线程安全的。但是我这个是一个用 netty 写的持久化服务器,所以是线程安全的,可以加上 @Sharable。
    wc951
    wc951
    May 23, 2019 via Android
    17
    用构造器注入就不会出现你这种疑惑,因为直接启动就失败了,这也是 spring 官方推荐构造器注入的原因
    brust
    brust
    May 23, 2019
    18
    用 spring4.0 出现过这种情况,但是 springboot 我还没遇到过,可以说下你的 spring 版本吗
    tedzhou1221
    tedzhou1221
    May 23, 2019 via Android❤️1
    19
    题外话:建议你用 idea,或者学习怎么用。
    当前类如果被 spring 管理的话,左边是有绿色的叶子,.
    @Autowired 如果生效的话左边也有绿色的豆子(Bean)

    所以大部分情况下,有没有注入成功,一眼就看出来
    brust
    brust
    May 23, 2019
    20
    我当时的解决方法是吧 @Autowired 换成 @resource
    szq8014
    szq8014
    May 23, 2019
    21
    @gramyang 从你目前的情况来看个人觉得用 ApplicationContext.getBean(clazz) 更方便一些,至于 ApplicationContext 怎么拿,最简单的方法就是 springboot 的 main 方法里面唯一的那行调用其实是有返回值的,而且返回值就是那个 ApplicationContext
    BBCCBB
    BBCCBB
    May 23, 2019
    22
    这个的确是你用法不对...
    ala2008
    ala2008
    May 23, 2019
    23
    ioc 了解一下
    linyinma
    linyinma
    May 23, 2019
    24
    小哥拉屎拉不出来乖茅坑没设计好~~
    Yuicon
    Yuicon
    May 23, 2019
    25
    学习理论的重要性
    liujan
    liujan
    May 23, 2019
    26
    spring 注入的话需要保证被注入的类和注入的类都在 spring 的 bean 容器了。可以加 @Component
    rffan
    rffan
    May 23, 2019
    27
    你这个是基本不了解 Spring 啊不是坑啊。
    hailiang88
    hailiang88
    May 23, 2019
    28
    先尝试下手撸个 ioc 吧
    Ahaochan
    Ahaochan
    May 23, 2019
    29
    在非 Spring 管理的类下, 使用 SpringContextHolder 解决. 注意初始化顺序.

    https://github.com/Ahaochan/project/blob/master/ahao-utils/src/main/java/com/ahao/util/spring/SpringContextHolder.java
    gramyang
    gramyang
    OP
    May 23, 2019
    30
    @Ahaochan 我就是这么解决的,这个是正解
    zcating
    zcating
    May 23, 2019
    31
    兄 dei,要么你就为这个类添加注解 @Component,要么就写个 config,为 NettyHandler 写个工厂方法 ,在工厂方法上添加注解 @Bean。
    gabon
    gabon
    May 23, 2019 via Android
    32
    菜
    kangzai50136
    kangzai50136
    May 23, 2019 via Android
    33
    多了解 Spring 吧。
    brust
    brust
    May 23, 2019
    34
    @tedzhou1221 我 idea 怎么没绿色豆子,可以截图标志 发链接看看嘛,或者邮箱 YnJ1c3RAYnJ1c3QuY24=
    arthas2234
    arthas2234
    May 23, 2019
    35
    handle 类上面加 @Component 注解
    @ComponentScan 的配置也要确保你的 handle 被扫描到
    Chinsung
    Chinsung
    May 23, 2019
    36
    Spring 只管理你所配合的类,通过注解、javaconfig、xml 这 3 个配置的类。通过这 3 者配置起来的类互相之间才能由 spring 管理依赖关系。
    你这个 handler 要加上 @Compoment 注解,然后再启动类上加上 CompomentScan 或者在 xml 里配置 CompomentScan,这个类才能应用 Autowire 等注解注入依赖
    EastLord
    EastLord
    May 26, 2019
    37
    其实现在不用 @Autowired 也行,直接构造注入
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1116 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 78ms · UTC 23:47 · PVG 07:47 · LAX 15:47 · JFK 18:47
    ♥ Do have faith in what you're doing.