@Autowired注解在抽象类中失效的原因及解决

 更新时间:2021年08月14日 11:32:52   作者:jy的blog  
这篇文章主要介绍了@Autowired注解在抽象类中失效的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@Autowired注解在抽象类中失效

最近在工作中遇到这个问题,在抽象类中使用Autowired这个注解,注入mybatis的dao时,总是出现空指针异常,通过日志的打印,发现是这个dao注入失败为空。然后通过new出spring上下文对象,再去调用getBean()方法,获取到这个注入的dao,这样是可行的,但是总是觉得这不是最佳实践,一定有比这个更加优雅的方式能解决这个问题。

我们来还原一下这个问题:

1.定义一个抽象类

声明为spring组件,在其中自动装配另一个bean:

 @Component
 public abstract class BaseService {
      @Autowired
      Dao dao;
  }

2.然后在他的子类中使用这个自动装配的对象

 @Component
 public class myService extends BaseService{
     public void print(){
         //运行时为null
         System.out.print(dao.toString());
     }
 }

在我们实例化子类对象的时候,抽象父类不能实例化,因为spring注入的是实例对象,而不是类,所以spring不会将dao自动装配注入到一个实例中。但是我们通过在在抽象类中获取的上下文对象中却可以拿到dao,因为这个上下文对象

是我们自己手动new出来的,不是spring通过反射注入到对象中去的。因此这种方案是可行的。

下面介绍一种更优雅的解决方案:

1.同样是定义一个抽象类

 public class BaseService {
     Dao dao;
 }
 

2.在子类中使用注解

@Component
public class myService extends BaseService{
    //Autowired修饰方法时,根据方法参数类型判断实例化哪个类
    @Autowired 
    public void printDao(Dao dao){
        super.dao = dao;//父类属性注入
    }
    public void print(){
        System.out.print(dao.toString());
    }
}

这样写是不是要比我们直接去new applicationContext更加优雅呢?

在抽象类中使用@Autowired

1.简介

在本快速教程中,我们将说明如何在抽象类中使用 @Autowired 自动装配注解。

我们将 @Autowired 应用于 abstract 抽象类,并关注此时要考虑的重点。

2.Setter 方式注入

我们可以在设置方法上使用_@Autowired_:

public abstract class BallService {
    private LogRepository logRepository;
    @Autowired
    public final void setLogRepository(LogRepository logRepository) {
        this.logRepository = logRepository;
    }
}

当我们使用_@Autowired_上setter方法,我们应该用final 关键字,这样子类便不能覆盖setter方法。否则,注解将无法正常运行。

3.构造函数注入

我们不能在抽象类的构造函数上使用_@Autowired_。

Spring 不会在抽象类的构造函数上解析 @Autowired 注解。子类应为 super 构造函数提供必要的参数。

相反,我们应该在子类的构造函数上使用_@Autowired_:

public abstract class BallService {
    private RuleRepository ruleRepository;
    public BallService(RuleRepository ruleRepository) {
        this.ruleRepository = ruleRepository;
    }
}
@Component
public class BasketballService extends BallService {
    @Autowired
    public BasketballService(RuleRepository ruleRepository) {
        super(ruleRepository);
    }
}

4.备忘单

让我们总结一些要记住的规则。

首先,抽象类不会进行组件扫描,因为没有具体的子类就无法实例化。

其次,在抽象类中可以进行setter注入,但是如果不对setter方法使用_final_关键字,因而存在一定误用的风险。如果子类覆盖 setter 方法,则应用程序可能不能正常运行。

第三,由于 Spring 在抽象类中不支持构造函数注入,因此通常应该让具体的子类提供构造函数参数。这意味着我们需要在具体子类中依赖构造函数注入。

最后,将构造函数注入用于必需的依赖项,并将setter注入用于可选的依赖项是一个很好的经验法则。但是,正如我们可以从抽象类的一些细微差别中看到的那样,通常在这里构造函数注入更为有利。

因此,实际上我们可以说具体的子类控制着它的抽象父类如何获得其依赖项。 Spring 在装配子类时, 会对其依赖进行注入。

5.结论

在本文中,我们练习了在抽象类中使用_@Autowired_,并解释了一些关键点。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot监听应用程序启动的生命周期事件的四种方法

    SpringBoot监听应用程序启动的生命周期事件的四种方法

    在 Spring Boot 中,监听应用程序启动的生命周期事件有多种方法,本文给大家就介绍了四种监听应用程序启动的生命周期事件的方法,并通过代码示例讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2024-07-07
  • SpringBoot之LogBack配置详解

    SpringBoot之LogBack配置详解

    这篇文章主要介绍了SpringBoot之LogBack配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • SpringBoot实现自定义启动器的示例详解

    SpringBoot实现自定义启动器的示例详解

    虽然Spring官方给我们提供了很多的启动器供我们使用,但有时候我们也会遇到某些特殊场景,这些启动器满足不了。这个时候就需要自定义一个启动器供我们使用,本文为大家介绍了SpringBoot实现自定义启动器的方法,希望对大家有所帮助
    2023-01-01
  • Spring Boot整合QueryDSL的实现示例

    Spring Boot整合QueryDSL的实现示例

    这篇文章主要介绍了Spring Boot整合QueryDSL的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • JDBC数据库连接过程及驱动加载与设计模式详解

    JDBC数据库连接过程及驱动加载与设计模式详解

    这篇文章主要介绍了JDBC数据库连接过程及驱动加载与设计模式详解,需要的朋友可以参考下
    2016-10-10
  • 关于spring 扫描不到jar中class文件的原因分析及解决

    关于spring 扫描不到jar中class文件的原因分析及解决

    这篇文章主要介绍了关于spring 扫描不到jar中class文件的原因分析及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • RabbitMQ 避免消息重复消费的方法

    RabbitMQ 避免消息重复消费的方法

    消费者端实现幂等性,意味着消息永远不会消费多次,即使收到了多条一样的消息,这篇文章给大家分享RabbitMQ 避免消息重复消费的方法,感兴趣的朋友一起看看吧
    2024-03-03
  • 分布式系统下调用链追踪技术面试题

    分布式系统下调用链追踪技术面试题

    这篇文章主要为大家介绍了分布式系统下调用链追踪技术面试问题合集,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-03-03
  • springboot 整合 seata的配置过程

    springboot 整合 seata的配置过程

    本文给大家介绍springboot 整合 seata的配置过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-08-08
  • Java 实现FTP服务实例详解

    Java 实现FTP服务实例详解

    这篇文章主要介绍了Java 实现FTP服务实例详解的相关资料,需要的朋友可以参考下
    2017-04-04

最新评论