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

Spring-容器:IOC-基于注解管理Bean

目录

  • 一、基于注解管理Bean(重点)
    • 1.1、概述
    • 1.2、开启组件扫描
      • 1.2.1、指定要排除的组件
      • 1.2.2、仅扫描指定组件
    • 1.3、使用注解定义Bean
    • 1.4、使用@Autowired注入
      • 1.4.1、属性注入
      • 1.4.2、set注入
      • 1.4.3、构造方法注入
      • 1.4.4、形参注入
      • 1.4.5、无注解注入
      • 1.4.6、联合@Qualifier注解注入
    • 1.5、使用@Resource注入
      • 1.5.1、Name注入
      • 1.5.2、未知Name注入
      • 1.5.3、类型注入
    • 1.6、全注解开发

一、基于注解管理Bean(重点)

1.1、概述

简介

​ 从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

​ Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

步骤

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

使用注解

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean

在这里插入图片描述

1.2、开启组件扫描

概述

​ Spring 默认不支持注解装配 Bean,因此我们需要在 Spring 的 XML 配置中,通过 context:component-scan 元素开启 Spring Beans的自动扫描功能。开启此功能后,Spring 会自动从扫描指定的包(base-package 属性设置)及其子包下的所有类,如果类上使用了 @Component 注解,就将该类装配到容器中。

  • 步骤一:添加约束

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">
    </beans>
    
  • 步骤二:开启扫描方式

    <context:component-scan base-package="com.atguigu.spring6">
    </context:component-scan>
    

1.2.1、指定要排除的组件

<context:exclude-filter></context:exclude-filter>标签,指定排除规则

  • type属性:设置排除或包含的依据
    • annotation,根据注解排除
    • assignable,根据类型排除
  • expression属性:设置要排除的注解或类型的全类名
<context:component-scan base-package="com.atguigu.spring6"><!-- context:exclude-filter标签:指定排除规则 --><!-- type:设置排除或包含的依据type="annotation",根据注解排除,expression中设置要排除的注解的全类名type="assignable",根据类型排除,expression中设置要排除的类型的全类名--><context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!--<context:exclude-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>

1.2.2、仅扫描指定组件

  • use-default-filters="false",表示关闭默认扫描规则
  • <context:include-filter></context:include-filter>,表示指定的过滤条件来确定哪些类应该被包含在组件扫描中
<context:component-scan base-package="com.atguigu" use-default-filters="false"><!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 --><!-- use-default-filters属性:取值false表示关闭默认扫描规则 --><!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 --><context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/><!--<context:include-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
</context:component-scan>

1.3、使用注解定义Bean

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean
在这里插入图片描述

1.4、使用@Autowired注入

单独使用@Autowired注解时,默认是根据类型装配

  • @Autowired注解可以标注在:构造方法上、方法上、形参上、属性上、注解上
  • @Autowired注解的required属性,
    • 属性值为True:表示注入的时候要求被注入的Bean必须是存在的,如果不存在则报错
    • 属性值为False::表示注入的时候要求被注入的Bean不一定是存在的,如果存在的话就注入,不存在的话,也不报错

1.4.1、属性注入

在这里插入图片描述
当使用@Autowired注解注入时,可不提供构造方法喝Setter方法,也可以注入成功

1.创建UserDao接口

package com.atguigu.spring6.dao;
public interface UserDao {public void print();
}

2.创建UserDaoImpl实现

package com.atguigu.spring6.dao.impl;
import com.atguigu.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

3.创建UserService接口

package com.atguigu.spring6.service;
public interface UserService {public void out();
}

4.创建UserServiceImpl实现类

package com.atguigu.spring6.service.impl;
import com.atguigu.spring6.dao.UserDao;
import com.atguigu.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {//注入dao//属性注入@Autowired//根据类型找到对应对象,完成注入private UserDao userDao;@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

5.创建UserController类

package com.atguigu.spring6.controller;
import com.atguigu.spring6.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {//注入service//属性注入@Autowired//根据类型找到对应对象,完成注入private UserService userService;public void out() {userService.out();System.out.println("Controller层执行结束。");}
}

步骤二:演示

@Test
public void testAnnotation(){ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");UserController userController = context.getBean("userController", UserController.class);userController.out();
}

1.4.2、set注入

1.修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Autowired//set方法注入public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

2.修改UserController类

@Controller
public class UserController {private UserService userService;@Autowired//set方法注入public void setUserService(UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}
}

1.4.3、构造方法注入

1.修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {private UserDao userDao;@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

2.修改UserController类

@Controller
public class UserController {private UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}}

1.4.4、形参注入

1.修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(@Autowired UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

2.修改UserController类

@Controller
public class UserController {private UserService userService;public UserController(@Autowired UserService userService) {this.userService = userService;}public void out() {userService.out();System.out.println("Controller层执行结束。");}
}

1.4.5、无注解注入

当有参数的构造方法只有一个时,@Autowired注解可以省略
1.修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

1.4.6、联合@Qualifier注解注入

当需要注入的接口有多个实现类时,可以联合使用@Qualifier(“userDaoImpl”) 注解,并指定实现类的名字,即可完成属性注入
1.添加UserDaoRedisImpl类

@Repository
public class UserDaoRedisImpl implements UserDao {@Overridepublic void print() {System.out.println("Redis Dao层执行结束");}
}

说明:

  • 此时,添加实现UserDao接口类,已经造成一个接口对应两个实现类
  • 此时,程序错误,信息中说:不能装配,UserDao这个Bean的数量等于2

步骤二:修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {@Autowired@Qualifier("userDaoImpl") // 指定bean的名字private UserDao userDao;@Overridepublic void out() {userDao.print();System.out.println("Service层执行结束");}
}

1.5、使用@Resource注入

@Resource注解是通过名称匹配的方式来实现注入的,默认按照名称进行匹配,未指定名称,使用属性名作为name,如果找不到匹配的名称,则会尝试按照类型匹配

用在属性上、set方法上

如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖

<dependency><groupId>jakarta.annotation</groupId><artifactId>jakarta.annotation-api</artifactId><version>2.1.1</version>
</dependency>

1.5.1、Name注入

1.修改UserDaoImpl类

package com.atguigu.spring6.dao.impl;import com.atguigu.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository("myUserDao")
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

当使用注解时,在小括号内写上属性名称表示为此Bean定义别名

2.修改UserServiceImpl类

package com.atguigu.spring6.service.impl;import com.atguigu.spring6.dao.UserDao;
import com.atguigu.spring6.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Resource(name = "myUserDao")private UserDao myUserDao;@Overridepublic void out() {myUserDao.print();System.out.println("Service层执行结束");}
}

当使用@Resource注解时,可以使用name属性指定属性注入的别名

1.5.2、未知Name注入

1.修改UserDaoImpl类

package com.atguigu.spring6.dao.impl;import com.atguigu.spring6.dao.UserDao;
import org.springframework.stereotype.Repository;@Repository("myUserDao")
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

2.修改UserServiceImpl类

package com.atguigu.spring6.service.impl;import com.atguigu.spring6.dao.UserDao;
import com.atguigu.spring6.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao myUserDao;@Overridepublic void out() {myUserDao.print();System.out.println("Service层执行结束");}
}

当使用@Resource注解时,在name属性未知的情况下,将属性注入的成员属性变量名定义为与Bean同名,即可完成注入

1.5.3、类型注入

1.原UserDaoImpl类

@Repository("myUserDao")
public class UserDaoImpl implements UserDao {@Overridepublic void print() {System.out.println("Dao层执行结束");}
}

2.修改UserServiceImpl类

@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao1;@Overridepublic void out() {userDao1.print();System.out.println("Service层执行结束");}
}

当使用@Resource注解时,现在userDao1属性名不存在,但仍然可以注入成功。因为,UserDao他们的类型名相同

1.6、全注解开发

​ 全注解开发就是不再使用spring配置文件了,写一个配置类来代替配置文件

使用@ComponentScan注解,进行组件扫描,从而替代了原有在xml文件中的配置

步骤一:创建配置类

@Configuration
//@ComponentScan({"com.atguigu.spring6.controller", "com.atguigu.spring6.service","com.atguigu.spring6.dao"})
@ComponentScan("com.atguigu.spring6")
public class Spring6Config {
}

步骤二:演示

​ 需要使用AnnotationConfigApplicationContext类来获取Spring6Config的字节码文件

@Test
public void testAllAnnotation(){ApplicationContext context = new AnnotationConfigApplicationContext(Spring6Config.class);UserController userController = context.getBean("userController", UserController.class);userController.out();logger.info("执行成功");
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • xxl-job升级到springboot3.0 导致页面打不开报错)问题
  • 语法分析例题
  • GAMES101(5~6节,光栅化)
  • C++ | Leetcode C++题解之第389题找不同
  • 通过15张图带你掌握网络抓包工具Wireshark必备使用技巧
  • 解决职业摔跤手分类问题的算法与实现
  • MySQL 数据库管理与操作指南
  • 数据结构之“双向链表”
  • 海外合规|新加坡网络安全认证计划简介(一)
  • k8s集群的调度
  • 如何使用事件流相关操作
  • WHAT - React 函数与 useMemo vs useCallback
  • 打工人应了解的裁员大礼包法律知识
  • c++的面向过程与面向对象
  • HNU-2023电路与电子学-实验1
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 【腾讯Bugly干货分享】从0到1打造直播 App
  • Django 博客开发教程 8 - 博客文章详情页
  • ES6系统学习----从Apollo Client看解构赋值
  • Github访问慢解决办法
  • Laravel 菜鸟晋级之路
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Mysql数据库的条件查询语句
  • orm2 中文文档 3.1 模型属性
  • Otto开发初探——微服务依赖管理新利器
  • SpriteKit 技巧之添加背景图片
  • Wamp集成环境 添加PHP的新版本
  • windows下如何用phpstorm同步测试服务器
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 让你的分享飞起来——极光推出社会化分享组件
  • 使用parted解决大于2T的磁盘分区
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 云大使推广中的常见热门问题
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​字​节​一​面​
  • #13 yum、编译安装与sed命令的使用
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • #QT(QCharts绘制曲线)
  • #传输# #传输数据判断#
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (2)从源码角度聊聊Jetpack Navigator的工作流程
  • (24)(24.1) FPV和仿真的机载OSD(三)
  • (C语言)逆序输出字符串
  • (ZT)一个美国文科博士的YardLife
  • (补)B+树一些思想
  • (分布式缓存)Redis哨兵
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (七)Appdesigner-初步入门及常用组件的使用方法说明
  • (限时免费)震惊!流落人间的haproxy宝典被找到了!一切玄妙尽在此处!
  • (一一四)第九章编程练习
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .bat批处理(十):从路径字符串中截取盘符、文件名、后缀名等信息
  • .net core使用EPPlus设置Excel的页眉和页脚