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

Spring使用注解进行注入

目录

前言

一、属性注入

1.1 属性注入的优缺点分析

二、Setter注入

2.1 Setter注入优缺点分析

三、构造方法注入

3.1 构造注入的优缺点

四、@Qualifier注解

五、@Resource注解

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


前言

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


一、属性注入

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

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

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

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

<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>
@Service
public class UserService1 {
    // 使用注解对这个userDao对象进行注入
    @Autowired
    private UserDao userDao;

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

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

1.1 属性注入的优缺点分析

优点:

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

缺点:

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

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

二、Setter注入

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

@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方法所以都能调用

三、构造方法注入

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

@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中注入两个相同的对象

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中创建两次

@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中有两个相同的对象。这样获取就会报错

@Controller
public class UserController {
    @Autowired
    private User user;
    public void test() {
        System.out.println(user);
    }
}
@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则打印的是“李四”

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

五、@Resource注解

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

@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不支持构造方法注入

 


http://www.kler.cn/news/108353.html

相关文章:

  • 网络综合和简化实频理论学习概述
  • mysql查看数据表文件的存放路径
  • python—openpyxl操作excel详解
  • react中的函数柯里化
  • DWA算法,仿真转为C用于无人机避障
  • CleanMyMac X2024永久免费版mac电脑管家
  • Vue 项目中使用 Pinia 状态管理详细教程
  • 06、SpringCloud -- 订单详情界面实现
  • 阿里云服务器—ECS快速入门
  • 黑客技术(网络安全)—小白自学
  • Jupyter Notebook还有魔术命令?太好使了
  • 【解决方案】ubuntu 解决办法 ImportError: cannot import name ‘_gi‘ from ‘gi‘
  • 软路由安装code-server配置和配置Nodejs开发环境
  • Lvs+Nginx+NDS
  • 【实用网站分享】
  • css四种导入方式
  • 【Python · PyTorch】线性代数 微积分
  • 【SPSS】基于RFM+Kmeans聚类的客户分群分析(文末送书)
  • 实现分片上传、断点续传、秒传 (JS+NodeJS)(TypeScript)
  • 视频上的水印文字如何去掉?
  • QT webengine显示HTML简单示例
  • was下log4j设置日志不输出问题
  • 【学习笔记】记录一个win 11 操作文件卡顿,Windows 资源管理器CPU占用飙升问题
  • Python对json文件的读取和处理
  • Netty对接阿里云语音识别和录音识别
  • DevOps与CI/CD的最佳实践
  • python随手小练10(南农作业题)
  • 【赠书活动】从瀑布模式到水母模式:ChatGPT如何赋能软件研发全流程
  • 79 电话号码的字母组合
  • 【Linux】解决缓存锁问题:无法获得锁 /var/lib/dpkg/lock-frontend