首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Java

Springboot 用 @Autowired 的坑

  •  
  •   gramyang · 148 天前 · 4471 次点击
    这是一个创建于 148 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我想很多老铁可能都碰到过,就是在 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 实例化
    }

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

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

    https://github.com/Ahaochan/project/blob/master/ahao-utils/src/main/java/com/ahao/util/spring/SpringContextHolder.java
        30
    gramyang   147 天前
    @Ahaochan 我就是这么解决的,这个是正解
        31
    zcating   147 天前
    兄 dei,要么你就为这个类添加注解 @Component,要么就写个 config,为 NettyHandler 写个工厂方法 ,在工厂方法上添加注解 @Bean
        32
    gabon   147 天前 via Android
        33
    kangzai50136   147 天前 via Android
    多了解 Spring 吧。
        34
    brust   147 天前
    @tedzhou1221 我 idea 怎么没绿色豆子,可以截图标志 发链接看看嘛,或者邮箱 YnJ1c3RAYnJ1c3QuY24=
        35
    arthas2234   147 天前
    handle 类上面加 @Component 注解
    @ComponentScan 的配置也要确保你的 handle 被扫描到
        36
    Chinsung   147 天前
    Spring 只管理你所配合的类,通过注解、javaconfig、xml 这 3 个配置的类。通过这 3 者配置起来的类互相之间才能由 spring 管理依赖关系。
    你这个 handler 要加上 @Compoment 注解,然后再启动类上加上 CompomentScan 或者在 xml 里配置 CompomentScan,这个类才能应用 Autowire 等注解注入依赖
        37
    EastLord   144 天前
    其实现在不用 @Autowired 也行,直接构造注入
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4243 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 27ms · UTC 01:40 · PVG 09:40 · LAX 18:40 · JFK 21:40
    ♥ Do have faith in what you're doing.