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

作者:jy的blog 时间:2021-07-15 06:12:04 

@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_,并解释了一些关键点。

来源:https://www.cnblogs.com/jy107600/p/7490390.html

标签:@Autowired注解,抽象类,失效
0
投稿

猜你喜欢

  • java获取系统路径字体、得到某个目录下的所有文件名、获取当前路径

    2023-11-29 14:39:23
  • MyBatis中使用$和#所遇到的问题及解决办法

    2023-03-25 12:27:55
  • Java模拟有序链表数据结构的示例

    2023-09-26 22:25:30
  • 十分钟理解Java中的动态代理

    2022-05-16 04:53:19
  • java int类型二维数组实现“杨辉三角”的完整实例

    2022-10-05 19:31:49
  • 举例说明Java设计模式编程中ISP接口隔离原则的使用

    2023-11-20 11:07:40
  • Java 动态数组的实现示例

    2022-02-27 07:05:25
  • springboot拦截器过滤token,并返回结果及异常处理操作

    2023-02-19 11:45:50
  • Java基础:流Stream详解

    2023-11-29 06:11:14
  • java实现动态 代理方法浅析

    2023-11-28 23:33:59
  • Springboot启动后执行方法小结

    2022-09-26 22:12:02
  • SpringBoot Nacos实现自动刷新

    2023-09-16 04:17:09
  • 一文详解Java抽象类到底有多抽象

    2023-08-27 01:41:26
  • Java+opencv3.2.0实现人脸检测功能

    2022-11-27 10:36:42
  • Java JDK11基于嵌套的访问控制的实现

    2021-07-11 10:02:05
  • 基于java ssm springboot+mybatis酒庄内部管理系统设计和实现

    2023-09-24 23:51:17
  • @PathVariable和@RequestParam传参为空问题及解决

    2023-01-06 02:27:00
  • SpringBoot2 参数管理实践之入参出参与校验的方式

    2022-12-25 02:44:30
  • SpringBoot如何使用自定义注解实现接口限流

    2023-11-25 07:22:37
  • 详解Mybatis通用Mapper介绍与使用

    2023-11-29 08:49:08
  • asp之家 软件编程 m.aspxhome.com