Spring使用注解进行注入

目录

前言

一、属性注入

[1.1 属性注入的优缺点分析](#1.1 属性注入的优缺点分析)

二、Setter注入

[2.1 Setter注入优缺点分析](#2.1 Setter注入优缺点分析)

三、构造方法注入

[3.1 构造注入的优缺点](#3.1 构造注入的优缺点)

四、@Qualifier注解

五、@Resource注解

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


前言

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


一、属性注入

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

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

java 复制代码
@Repository
public class UserDao {
    public void login() {
        System.out.println("---数据库核心操作---");
    }
}

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

XML 复制代码
<bean id="userDao" class="com.gl.demo.dao.UserDao"/>
 
<bean id="userService1" class="com.gl.demo.service.UserService1">
    <property name="userDao">
        <ref bean="userDao"/>
    </property>
</bean>
java 复制代码
@Service
public class UserService1 {
    // 使用注解对这个userDao对象进行注入
    @Autowired
    private UserDao userDao;

    public void login() {
        userDao.login();
    }
}
java 复制代码
@Test
public void test1() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    UserService1 userService = ctx.getBean("userService1", UserService1.class);
    userService.login();
}

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

1.1 属性注入的优缺点分析

优点:

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

缺点:

  • 无法为final修饰的变量进行注入
  • 通用性差,无法移植到非IO C容器中使用
  • 不符合单一设计原则

二、Setter注入

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

java 复制代码
@Service
public class UserService2 {
    private UserDao userDao;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void login() {
        System.out.println("Setter注入");
        userDao.login();
    }
}

2.1 Setter注入优缺点分析

优点:

  • 符合单一设计原则

缺点:

  • 不能给final修饰的变量注入
  • 注入的对象可以被修改,由于是setter方法所以都能调用

三、构造方法注入

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

java 复制代码
@Service
public class UserService3 {
    private UserDao userDao;

    @Autowired
    public UserService3(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void login() {
        System.out.println("构造注入");
        userDao.login();
    }
}

3.1 构造注入的优缺点

优点:

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

缺点:

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

四、@Qualifier注解

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

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

java 复制代码
public class User {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

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

java 复制代码
@Component
public class Users {
    @Bean
    public User user1() {
        User user = new User();
        user.setName("张三");
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.setName("李四");
        return user;
    }
}

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

java 复制代码
@Controller
public class UserController {
    @Autowired
    private User user;
    public void test() {
        System.out.println(user);
    }
}
java 复制代码
@Test
public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    UserController users = ctx.getBean("userController", UserController.class);
    users.test();
}

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

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

java 复制代码
@Controller
public class UserController {
    @Autowired
    @Qualifier("user1")
    private User user;
    public void test() {
        System.out.println(user);
    }
}

五、@Resource注解

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

java 复制代码
@Controller
public class UserController {
    //@Autowired
    //@Qualifier("user1")
    @Resource(name = "user2")
    private User user1;
    public void test() {
        System.out.println(user1);
    }
}

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

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

  • @Resource是Java自带的,@Autowired是Spring提供的的
  • 相比于@Autowired来说@Resource支持更多的参数设置,例如name等
  • @Autowired支持三种注入方式,但是@Resource不支持构造方法注入
相关推荐
@CLoudbays_Martin111 分钟前
CDN是否能有效检测并且同时防御Ddos 和 CC 攻击?
java·服务器·网络·数据库·git·数据库开发·时序数据库
阿杆11 分钟前
文心快码 3.5S 发布!实测插件开发,Architect 模式令人惊艳
前端·后端·文心快码
文心快码BaiduComate12 分钟前
我用Comate搭建「公园找搭子」神器,再也不孤单啦~
前端·后端·微信小程序
知彼解己37 分钟前
字符串大数相加:从初稿到优化的思路演进
java·开发语言·算法
计算机毕业设计指导1 小时前
基于Spring Boot + Vue 3的社区养老系统设计与实现
vue.js·spring boot·后端
拾忆,想起1 小时前
Redisson 分布式锁的实现原理
java·开发语言·分布式·后端·性能优化·wpf
焰火19991 小时前
[Java][SpringBoot]AspectJ切面配合自定义注解实现权限校验
java
几颗流星1 小时前
Rust 常用语法速记 - 解构赋值
后端·rust
我想当数字游民1 小时前
Go的切片是什么?一些小细节和容易错的地方
后端·golang
肖焱1 小时前
Java中的集合类有哪些?如何分类的?
后端