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不支持构造方法注入
相关推荐
小比卡丘1 小时前
C语言进阶版第17课—自定义类型:联合和枚举
android·java·c语言
xmh-sxh-13141 小时前
java 数据存储方式
java
liu_chunhai1 小时前
设计模式(3)builder
java·开发语言·设计模式
姜学迁1 小时前
Rust-枚举
开发语言·后端·rust
爱学习的小健1 小时前
MQTT--Java整合EMQX
后端
北极小狐2 小时前
Java vs JavaScript:类型系统的艺术 - 从 Object 到 any,从静态到动态
后端
ya888g2 小时前
GESP C++四级样题卷
java·c++·算法
【D'accumulation】2 小时前
令牌主动失效机制范例(利用redis)注释分析
java·spring boot·redis·后端
小叶学C++2 小时前
【C++】类与对象(下)
java·开发语言·c++
2401_854391082 小时前
高效开发:SpringBoot网上租赁系统实现细节
java·spring boot·后端