• Spring使用注解进行注入


    目录

    前言

    一、属性注入

    1.1 属性注入的优缺点分析

    二、Setter注入

    2.1 Setter注入优缺点分析

    三、构造方法注入

    3.1 构造注入的优缺点

    四、@Qualifier注解

    五、@Resource注解

    六、@Resource注解与@Autowired注解的区别


    前言

    在之前我们就已经了解过了Spring依赖注入的方式,但是前面所说的方式是通过配置文件的方式去进行依赖注入的,我们说配置文件的方式是比较麻烦的,所以在这里将使用注解的方式进行依赖注入。在Spring中使用注解进行依赖注入主要有3种方式:属性注入、Setter注入、构造方法注入。在使用之前先介绍两种常用的注解@Autowired、@Resource下面一起来看


    一、属性注入

    属性注入是后面开发过程中使用最多的一种方式,即在属性中直接添加注解进而完成注解的效果。

    首先创建一个UserDao类,为这个类添加注解(表示将对象存储在Spring中),这里的这个类是与数据库交互的

    1. @Repository
    2. public class UserDao {
    3. public void login() {
    4. System.out.println("---数据库核心操作---");
    5. }
    6. }

    创建一个UserService类调用UserDao,这里就需要在UserService类中创建一个userDao对象,进而使用这个对象来调用其核心方法。以往使用的是配置文件的Bean标签的方式,现在只需要一个简单的注解就可以完成这个这个繁琐的过程了

    1. <bean id="userDao" class="com.gl.demo.dao.UserDao"/>
    2. <bean id="userService1" class="com.gl.demo.service.UserService1">
    3. <property name="userDao">
    4. <ref bean="userDao"/>
    5. property>
    6. bean>
    1. @Service
    2. public class UserService1 {
    3. // 使用注解对这个userDao对象进行注入
    4. @Autowired
    5. private UserDao userDao;
    6. public void login() {
    7. userDao.login();
    8. }
    9. }
    1. @Test
    2. public void test1() {
    3. ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    4. UserService1 userService = ctx.getBean("userService1", UserService1.class);
    5. userService.login();
    6. }

    通过上述操作我们发现注解的属性注入确实方便了不少,但是属性注入的方式也是存在缺点的

    1.1 属性注入的优缺点分析

    优点:

    • 使用方便,只需要变量上面加一个@Autowired即可
    • 代码简洁,可读性高

    缺点:

    • 无法为final修饰的变量进行注入

    • 通用性差,无法移植到非IOC容器中使用
    • 不符合单一设计原则

    二、Setter注入

    这里的Setter注入也就是为这个变量添加一个setter方法,这里添加注解就是添加在setter方法上了,由于这里的测试方法都是一样的,所以这里就不再演示了

    1. @Service
    2. public class UserService2 {
    3. private UserDao userDao;
    4. @Autowired
    5. public void setUserDao(UserDao userDao) {
    6. this.userDao = userDao;
    7. }
    8. public void login() {
    9. System.out.println("Setter注入");
    10. userDao.login();
    11. }
    12. }

    2.1 Setter注入优缺点分析

    优点:

    • 符合单一设计原则

    缺点:

    • 不能给final修饰的变量注入

    • 注入的对象可以被修改,由于是setter方法所以都能调用

    三、构造方法注入

    构造方法顾名思义就是,使用构造方法的方法为变量注入,将注解添加在构造方法上即可

    1. @Service
    2. public class UserService3 {
    3. private UserDao userDao;
    4. @Autowired
    5. public UserService3(UserDao userDao) {
    6. this.userDao = userDao;
    7. }
    8. public void login() {
    9. System.out.println("构造注入");
    10. userDao.login();
    11. }
    12. }

    3.1 构造注入的优缺点

    优点:

    • 可以为final修饰的变量进行注入
    • 不能被修改,由于构造方法只会被加载一次,所以不能被修改
    • 通用性更好,在非IOC容器也能够使用
    • 完全初始化,构造方法会在对象创建之前执行,所以会被完全初始化

    缺点:

    • 其实这个是官方推荐的方法,并没有什么明显的缺点,要说缺点的话就是没有属性注入简洁

    四、@Qualifier注解

    在介绍了@Autowired注解进行注入之后,为什么还要有一个@Resource注解进行注入呢?接下来看一个案例,我们使用@Bean注解将同一个对象注入Spring两次,那么再通过@Autowired注解进行注入会发生什么呢?

    首先创建一个User类,再创建一个Users类往Spring中注入两个相同的对象

    1. public class User {
    2. private String name;
    3. public String getName() {
    4. return name;
    5. }
    6. public void setName(String name) {
    7. this.name = name;
    8. }
    9. @Override
    10. public String toString() {
    11. return "User{" +
    12. "name='" + name + '\'' +
    13. '}';
    14. }
    15. }

    这里使用@Bean注解将同一个对象再Spring中创建两次

    1. @Component
    2. public class Users {
    3. @Bean
    4. public User user1() {
    5. User user = new User();
    6. user.setName("张三");
    7. return user;
    8. }
    9. @Bean
    10. public User user2() {
    11. User user = new User();
    12. user.setName("李四");
    13. return user;
    14. }
    15. }

    通过@Autowired进行依赖注入,一般情况下这里的注入是没有问题的,但是在Spring中有两个相同的对象。这样获取就会报错

    1. @Controller
    2. public class UserController {
    3. @Autowired
    4. private User user;
    5. public void test() {
    6. System.out.println(user);
    7. }
    8. }
    1. @Test
    2. public void test() {
    3. ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    4. UserController users = ctx.getBean("userController", UserController.class);
    5. users.test();
    6. }

    这里的报错信息大概就是,找到了两个user对象分别是user1和user2,不知道你需要的是哪一个 

    这里的解决方法就是引入一个新的注解@Qualifier来限制注入的对象是哪一个。(在@Bean注解中方法名就是创建对象的id当然也可以在@Bean注解中自定义id)同理,如果@Qualifier中是user2则打印的是“李四”

    1. @Controller
    2. public class UserController {
    3. @Autowired
    4. @Qualifier("user1")
    5. private User user;
    6. public void test() {
    7. System.out.println(user);
    8. }
    9. }

    五、@Resource注解

    通过上面的案例我们发现使用两个注解解决问题还是有点麻烦,那么还有什么解决办法呢?这里使用JDK提供的@Resource注解来解决这个问题。那么为什么不直接在@Autowired注解中添加类限定名呢?那是因为@Autowired没有这个功能,这里我们查看源码也可以发现。这里的这个参数表示注入的时候这个Bean是否存在

    1. @Controller
    2. public class UserController {
    3. //@Autowired
    4. //@Qualifier("user1")
    5. @Resource(name = "user2")
    6. private User user1;
    7. public void test() {
    8. System.out.println(user1);
    9. }
    10. }

    最后使用@Resource注解的时候也是可以实现注入功能的

    六、@Resource注解与@Autowired注解的区别

    • @Resource是Java自带的,@Autowired是Spring提供的的
    • 相比于@Autowired来说@Resource支持更多的参数设置,例如name等
    • @Autowired支持三种注入方式,但是@Resource不支持构造方法注入

     

  • 相关阅读:
    图解八道经典指针笔试题
    【RocketMQ】消息的存储
    【StreamSets】StreamSets 表达式语言篇
    java毕业设计在线视频教育平台Mybatis+系统+数据库+调试部署
    DV,OV通配符的区别
    网络编程day05(IO多路复用)
    12 | JAVASE高级应用-集合
    A Review of Generalized Zero-Shot Learning Methods
    两个数组的交集 II 双指针 哈希表
    tp5连接多个数据库
  • 原文地址:https://blog.csdn.net/x2656271356/article/details/134054027