当前位置: 首页 > web >正文

spring--@Autowired

1.先了解什么是@Autowired

  @Autowired 是 Spring 框架中用于实现依赖自动注入的核心注解。它通过类型匹配自动装配 Spring 容器中的 Bean,极大简化了依赖管理。

2.使用@Autowired的场景

  2.1 @Autowired的使用

    1.首先有BookDaoBookDaoImplBookServiceBookServiceImplApp 

public interface BookDao {public void save();
}
@Repository
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
public interface BookService {public void save();
}
@Service
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}
}
//测试
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookService bookService = ctx.getBean(BookService.class);bookService.save();}
}

2.运行main方法肯定会有错误

        出现问题的原因是,在BookServiceImpl类中添加了BookDao的属性,并提供了setter方法,但是目前是没有提供配置注入BookDao的,所以bookDao对象为Null,调用其save方法就会报控指针异常

3.对于这个问题使用注解该如何解决?

        有很多种解决方式,本次我们使用@Autowired

(1) 在BookServiceImpl类的bookDao属性上添加@Autowired注解

@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;//     public void setBookDao(BookDao bookDao) {
//        this.bookDao = bookDao;
//    }public void save() {System.out.println("book service save ...");bookDao.save();}
}

注意:

  • @Autowired可以写在属性上,也可也写在setter方法上,最简单的处理方式是写在属性上并将setter方法删除掉(使用XML 配置注入必须要有set方法)

  • 为什么setter方法可以删除呢?

    • 自动装配基于反射设计创建对象并通过暴力反射为私有属性进行设值

    • 普通反射只能获取public修饰的内容

    • 暴力反射除了获取public修饰的内容还可以获取private修改的内容

    • 所以此处无需提供setter方法

(2)@Autowired是按照类型注入,那么对应BookDao接口如果有多个实现类,比如有BookDaoImpl2、BookDaoImpl2

@Repository
public class BookDaoImpl1 implements BookDao {public void save() {System.out.println("book dao save ...2");}
}
@Repository
public class BookDaoImpl2 implements BookDao {public void save() {System.out.println("book dao save ...2");}
}

这个时候再次运行App,就会报错

此时,按照类型注入就无法区分到底注入哪个对象,解决方案:按照名称注入

  • 先给两个Dao类分别起个名称

    @Repository("bookDao")
    public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
    }
    @Repository("bookDao2")
    public class BookDaoImpl2 implements BookDao {public void save() {System.out.println("book dao save ...2" );}
    }

    此时就可以注入成功,但是得思考个问题:

    • @Autowired是按照类型注入的,给BookDao的两个实现起了名称,它还是有两个bean对象,为什么不报错?

    • @Autowired默认按照类型自动装配,如果IOC容器中同类的Bean找到多个,就按照变量名和Bean的名称匹配因为变量名叫bookDao而容器中也有一个booDao,所以可以成功注入。

     分析下面这种情况是否能完成注入呢?

@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookDao bookDao;}
@Repository("bookDao1")
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ..." );}
}
@Repository("bookDao2")
public class BookDaoImpl2 implements BookDao {public void save() {System.out.println("book dao save ...2" );}
}
不行,因为按照类型会找到多个bean对象,此时会按照bookDao名称去找,因为IOC容器只有名称叫bookDao1bookDao2,所以找不到,会报NoUniqueBeanDefinitionException
2.2 注解实现按照名称注入

当根据类型在容器中找到多个bean,注入参数的属性名又和容器中bean的名称不一致,这个时候该如何解决,就需要使用到@Qualifier来指定注入哪个名称的bean对象。

@Service
public class BookServiceImpl implements BookService {@Autowired@Qualifier("bookDao1")private BookDao bookDao;public void save() {System.out.println("book service save ...");bookDao.save();}
}

@Qualifier注解后的值就是需要注入的bean的名称。

注意:@Qualifier不能独立使用,必须和@Autowired一起使用

http://www.xdnf.cn/news/15385.html

相关文章:

  • Wireshark的安装和基本使用
  • 第七章 算法题
  • Docker从环境配置到应用上云的极简路径
  • 【micro:bit】从入门到放弃(一):在线、离线版本的使用
  • 第三章-提示词-探秘大语言基础模型:认知、分类与前沿洞察(9/36)
  • C++:宏
  • 从零开始学习深度学习-水果分类之PyQt5App
  • LLaMA-Factory的webui快速入门
  • NLP-迁移学习
  • 海豚远程控制APP:随时随地,轻松掌控手机
  • [Rust 基础课程]选一个合适的 Rust 编辑器
  • Vue 3 动态ref问题
  • 如何将FPGA设计的验证效率提升1000倍以上(4)
  • MailSpring
  • python excel处理
  • python-enumrate函数
  • 字母异位词分组
  • Linux驱动09 --- 环境搭建
  • 计算机毕业设计Java停车场管理系统 基于Java的智能停车场管理系统开发 Java语言实现的停车场综合管理平台
  • 如何检测自动化设备中的直线导轨品质是否优良?
  • UE5多人MOBA+GAS 19、创建升龙技能,以及带力的被动,为升龙技能添加冷却和消耗
  • 【408考研知识点全面讲解计算机学科专业基础综合(408)】——数据结构之排序
  • SELECT ... INTO OUTFILE和LOAD DATA INFILE
  • 请求服务端获取broker的机房归属信息异常
  • 【C#】GraphicsPath的用法
  • ai批量抠图win和mac都可以用
  • 数据库连接池及其核心特点
  • Spring Boot整合MyBatis+MySQL+Redis单表CRUD教程
  • OneCode 3.0 DDD领域模型开放接口:基于DSMFactory的架构解析与实践指南
  • 创建 UIKit 项目教程