3. 基于注解方式管理Bean

2023-05-16

1. 什么是注解

(1)注解是代码中的特殊标记,格式为:@注解名称(属性名称=属性值, 属性名称=属性值, …)

(2)注解可以作用在类、方法、属性上面

(3)使用注解的目的:简化xml配置

2. 使用注解管理Bean

2.1 基于注解方式创建对象

2.1.1 注解说明

  • @Component
  • @Service
  • @Controller
  • @Repository

上面四个注解功能是一样的,都可以用来创建bean实例,为了区分不同层级的功能,因此建议不同的层级用不同注解进行表示

2.1.2 代码实现

  1. 引入依赖

    需要引入apo依赖

    image-20201217105640204

  2. 开启组件扫描

    <?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                               http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    
        <!-- 开启组件扫描
                1. 如果扫描多个包,多个包之间使用逗号分隔
                2. 直接扫描上次目录
         -->
        <context:component-scan base-package="com.study.spring5.demo10"></context:component-scan>
    </beans>
    
  3. 创建UserService类,在类上面添加创建对象的注解

    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Service;
    
    //@Component(value = "userService")
    //@Component
    @Service
    // 等同于在配置文件中写 <bean id="userService" class="...">
    // 在注解里面value属性值可以省略不写,默认值就是类名称的首字母小写 UserService => userService
    public class UserService {
    
        public void add() {
            System.out.println("service add");
        }
    }
    
  4. 创建主方法

    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("bean10.xml");
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    

2.2 组件扫描配置

UserService类

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;


//@Component(value = "userService")
//@Component
//@Service
@Controller // 由于配置文件的配置,只能使用@Controller注解才会被扫描到
// 等同于在配置文件中写 <bean id="userService" class="...">
// 在注解里面value属性值可以省略不写,默认值就是类名称的首字母小写 UserService => userService
public class UserService {

    public void add() {
        System.out.println("service add");
    }
}

xml配置文件

<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    <!-- 组件扫描配置 只扫描用Controller注解声明的类
            use-default-filters属性用来控制是否使用默认filter进行扫描
     -->
    <context:component-scan base-package="com.study.spring5.demo11" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


    <!-- 组件扫描配置 不扫描用Component注解声明的类 不需要配置 use-default-filters属性 -->
    <context:component-scan base-package="com.study.spring5.demo11">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    </context:component-scan>
</beans>

主方法

public class Main {

    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("bean11.xml");
        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.add();
    }
}

2.3 基于注解方式实现属性注入

2.3.1 注解说明

  • @Autowired

    根据属性类型进行自动注入

  • @Qualifier

    根据属性名称进行注入

  • @Resource

    可以根据类型注入,也可以根据名称注入

  • @Value

    注入普通类型属性

2.3.2 代码实现

  • @Autowired

    第一步:创建service和dao对象,在service和dao类添加创建对象的注解

    UserService类

    @Service
    public class UserService {
    
        public void add() {
            System.out.println("UserService::add");
        }
    }
    

    UserDao接口

    public interface UserDao {
    
        void add();
    }
    

    UserDao接口实现类UserDaoImpl

    @Repository
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    

    第二步:在service注入dao对象,在UserServiceImpl类添加UserDao类型属性

    将UserService改为以下内容

    @Service
    public class UserService {
    
        // 定义dao类型属性,不需要添加set方法
        // 添加注入属性注解
        @Autowired
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    

    主方法

    public class Main {
    
        public static void main(String[] args) {
            ApplicationContext applicationContext =
                    new ClassPathXmlApplicationContext("bean12.xml");
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    
  • @Qualifier

    需要和@Autowired一起使用

    用于当一个接口有多个实现类时候,按照名称注入指定的实现类

    UserDaoImpl改为

    @Repository(value = "userDaoImpl")
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    

    UserService改为

    @Service
    public class UserService {
    
        // 定义dao类型属性,不需要添加set方法
        // 添加注入属性注解
        @Autowired
        // 当有多个实现类时,按照指定的名称注入实现类,默认不写的话,则注入类名称首字母小写后的类 UserDao => userDao
        @Qualifier(value = "userDaoImpl")
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    
  • @Resource(spring不建议使用)

    JDK11版本及以上需要引用javax.annotation-api才可使用@Resource注解

    image-20201217154919317

    将UserService改为

    @Service
    public class UserService {
    
    //    @Resource
        @Resource(name = "userDaoImpl") // 根据名称进行注入
        private UserDao userDao;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
        }
    }
    
  • @Value

    UserService改写为

    @Service
    public class UserService {
    
    //    @Resource
        @Resource(name = "userDaoImpl") // 根据名称进行注入
        private UserDao userDao;
    
        @Value(value = "注入的名称")
        private String name;
    
        public void add() {
            System.out.println("UserService::add");
            userDao.add();
            System.out.println("注入的name值:" + name);
        }
    }
    

2.4 完全注解开发

  1. 创建配置类,替代xml配置文件

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    // 声明该类作为配置类
    @Configuration
    // @ComponentScan(basePackages = {"com.study.spring5.demo13"})
    // 等同于<context:component-scan base-package="com.study.spring5.demo13"/>
    @ComponentScan(basePackages = {"com.study.spring5.demo13"})
    public class SpringConfig {
        
    }
    
  2. 编写UserDao接口

    public interface UserDao {
    
        void add();
    }
    
  3. 编写UserDaoImpl实现类

    @Repository
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void add() {
            System.out.println("UserDaoImpl::add");
        }
    }
    
  4. 编写主方法

    public class Main {
    
        public static void main(String[] args) {
            // 加载配置类,通过配置类加载配置,替代掉xml
            ApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService = applicationContext.getBean("userService", UserService.class);
            userService.add();
        }
    }
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3. 基于注解方式管理Bean 的相关文章

  • 【进程控制上】创建、终止、等待、程序替换

    进程的创建 终止 等待 程序替换 以及popen system与fork之间的区别 一 进程的创建 init进程将系统启动后 xff0c init将成为此后所有进程的祖先 xff0c 此后的进程都是直接或间接从init进程 复制 而来 完成
  • 【进程控制下】实现一个简易的shell

    1 shell原理 运用程序替换的原理来实现的 xff0c shell自己就是一个进程 span class hljs number 1 span 获取命令行 span class hljs number 2 span 解析命令行 span
  • VIM的基本使用

    一 VIM 1 概念 是一款文本编辑器 xff0c 和Emacs并列成为类Unix系统用户最喜欢的文本编辑器 2 优点 可以完成复杂的编辑与格式化功能 3 模式 其模式共有十二种 xff0c 基本模式有六种 span class hljs
  • 进程信号

    一 信号概念 1 一个信号产生及处理实例 1 在shell下 xff0c 启动一个进程 2 按下Ctrl 43 c xff0c 键盘输入产生一个硬件中断 3 如果CPU正在运行这个进程则代码暂停执行 xff0c CPU从用户态返回到内核态
  • 进程间关系和守护进程

    一 进程间关系 1 进程组 xff08 Process Group xff09 1 xff09 是一个或多个进程的集合 xff0c 通常 xff0c 这个集合与同一个作业相关联 xff0c 可以接受同一终端的各种信号 2 xff09 每一个
  • 多线程死锁

    一 死锁 1 xff09 提出 多线程与多进程提高了系统资源的利用率 xff0c 然而并发执行也会带来一些问题 xff0c 如死锁 2 xff09 概念 死锁是指两个或两个以上的进程在执行过程中 xff0c 由于竞争资源或者由于彼此通信而造
  • Proxy-Server

    一 摘录 二 背景 由于某些原因 xff0c 在我们国内无法访问google facebook等外国网站 xff0c 如果你想使用外网来学习 xff0c 聊天 xff0c 那么就可以使用一些翻墙代理 三 原理 1 要想翻墙 xff0c 首先
  • 【线程】概念与控制

    线程概念与控制 线程分离 一 线程的概念 1 概念 在一个程序里的一个执行流就叫做线程 xff0c 是一个进程内部的控制序列 线程是调度的基本单位 xff0c 在Linux下 xff0c 线程称为轻量级进程 2 线程与进程之间的区别 1 x
  • 使用Linux能显著降低家用电脑或服务器的功耗?

    就那我家里的电费举例子吧 xff08 心疼 xff09 xff0c 我家上个月电费比平时多了50元 xff08 你能想到50元是都少度电吧 xff1f xff09 xff0c 原因就是就我使用了一个月Linux 这么说Linux能增加电费开
  • 【线程同步与互斥】卖票问题(互斥锁)

    一 简述 1 共享变量 很多变量有时候需要在线程间共享 xff0c 可以通过数据的共享 xff0c 从而完成线程之间的交互 如果变量是只读的 xff0c 多个线程同时读取该变量不会有一致性的问题 xff0c 但是当一个线程可以修改的变量 x
  • 【网络基础】基本协议

    一 协议 1 概念 计算机与计算机之间通过网络实现通信时事先达成的一种约定 两台计算机只要遵循相同的协议就能够实现通信 网络也属于进程间通信 xff0c 公共资源是网络 xff0c 其本质是两个进程通过网络进行收发数据 2 多任务调度 操作
  • 面试必备:”三次握手与四次挥手

    TCP是如何建立连接与断开 xff1f 如何提高可靠性 xff1f 又是如何提高性能的 xff1f 一 TCP的连接与断开 1 连接前的准备 服务端 xff1a 分配文件描述符 gt 绑定 gt 监听 gt 阻塞等待客户端连接 客户端 xf
  • 实现八大排序算法

    八大常用排序实现地址 xff1a https gitee com CCTVYI Algorithm tree master Sort 一 背景 1 稳定性 两个相等的数A和B xff0c 倘若在未排序前 xff0c A在B的前面 xff0c
  • 复杂链表的复制

    一 复杂链表 1 什么叫复杂链表 xff1f 每个节点中有一个节点值 xff0c 以及两个指针 xff0c 一个指向下一个节点 xff0c 另一个特殊指针指向任意一个节点或NULL 2 结构体 struct RandomListNode i
  • 高级IO模型

    一 网络IO 1 高级IO背景 对于网络IO xff0c IO效率提升是至关重要的 xff0c 一个数据在网络中的传输 xff0c 其传输时间主要由网络中的延迟所决定 xff0c 具有不确定性 xff08 什么时候来 xff09 xff0c
  • IO多路转接之select

    github链接 xff1a 通过代码讲解select 此代码先将数组初始化为 1 xff0c 在使用FD ISSET将事件全部设为读事件 xff0c 一旦发现有连接发起请求 xff0c 那么读事件就绪 xff0c 将该监听套接字fd添加到
  • IO多路转接之epoll

    github xff1a epoll代码 一 epoll 1 认识epoll 它是Linux内核为处理大批量句柄而做了改进的poll xff0c Linux下多路复用IO接口select poll的增强版本 xff0c 它能显著提高程序在大
  • IP地址与MAC地址缺一不可吗?

    答案是肯定的 xff0c 最近复习到了网络这块的知识 xff0c 才突然弄懂了 xff08 1 xff09 首先 xff0c 我们如果第一次将信息从A端发往B端 xff0c 那么信息需要从应用层到物理层一层一层进行封装 xff0c 到达对端
  • [剑指offer] 连续子数组最大和

    题目 xff1a 对于一个有正有负的整数数组 xff0c 请找出总和最大的连续数列 给定一个 span class hljs keyword int span 数组A和数组大小n xff0c 请返回最大的连续数列的和 1 思路 xff1a
  • Visual Studio连接wsl使用C/C++进行Linux开发

    首先打开Visual Studio xff0c 打开顶部菜单栏上的项目 然后选择属性 这样就会弹出一个窗口 xff0c 窗口的标题不重要 xff0c 我给项目起的名字叫Linux控制台项目 xff0c 他就显示成 Linux控制台项目 属性

随机推荐

  • 输入一个字符串,求字符串中包含的字符集合

    输入 xff1a abcqweracb 输出 xff1a abcqwer 一 剖析 采用数组的方式 xff0c 定义一个可以存放256个字符的数组 xff08 ASCII最多包含256个字符 xff09 xff0c 先将数组初始化1 xff
  • 求最小步数变为斐波那契数

    一 解析 xff1a 当我们一步一步走的时候 xff0c 一边计算斐波那契数 xff0c 一边计算左边的数和输入的N值进行差值运算 xff0c 直到N比斐波那契数小就直接退出 二 代码 span class hljs keyword int
  • 逆置链表

    题目 xff1a 将一个链表逆置 解析 xff1a 使用三个指针 xff0c 前 中 后 xff0c 改变中指针 xff0c 遍历后指针 ListNode ReverseList ListNode pHead span class hljs
  • 字符串中连续最长数字串

    一 题目要求 二 解析 使用左右下标来记录连续数字 xff0c 使用cur来记录最长连续数字的个数 三 代码 span class hljs preprocessor include lt iostream gt span using na
  • 输出链表中倒数第K个结点

    1 结构体类型 span class hljs keyword struct span ListNode span class hljs built in int span span class hljs keyword val span
  • C语言深度解剖

    一 关键字 1 关键字 是编译器能认识的特殊字符串符号 C语言共有32个关键字 xff0c 含sizeof xff0c 计算对象所占内存空间的大小 2 定义 创建一个对象并分配一块内存 3 声明 告诉编译器 xff0c 名字已经匹配到了一块
  • QT 实现窗口四周阴影

    网上好多写的不清楚 又搞了好长时间 这样应该最简单了 一 效果图 二 思路 1 先将所有窗口控件拖到一个QFrame里 xff0c 注意 xff0c QWidget与QFrame之间必须有间距 否则QFrame发散的阴影没有地方显示 2 设
  • cmd中执行批处理(.bat)文件,批处理文件调用python脚本

    记录我在cmd中操作遇到的一些问题 以及Bat脚本常用的一些命令 文章目录 一 bat批处理文件调用python脚本 xff0c 此时执行 bat文件出现了无模块的问题 xff08 安装python模块 xff09 二 cmd执行带参的ba
  • 修改window下的MessageBox中默认文字

    1 方法是修改系统的下的默认名称 放在博客上就当我记住了哈哈 xff01 include lt windef h gt LRESULT CALLBACK CBTHookProc int nCode WPARAM wParam LPARAM
  • 批处理脚本中切换目录

    一 场景 我要在bin main目录下操作v1文件 xff0c 然后在bin目录下操作v2文件 xff0c 但是最后v2文件没有被改写 xff0c 原因是你已经进入bin main 子目录下 xff0c 不能直接进入父目录bin 所以应该注
  • Linux下最强安卓模拟器,流畅又丝滑(附详细安装教程)此瓜保熟|Linux游戏党

    我打算完全从头开始 xff0c 写一个专门用于桌面办公的纯国产操作系统 xff0c 规避主流操作系统上影响用户体验的问题 xff0c 系统力求简洁 有兴趣加QQ群 xff1a 709652950 好东西让更多人发现 xff01 我找了整整两
  • python删除创建文件夹遇到的WindowsError: [Error 5]问题

    一 背景 实际操作中 xff0c 想删除一个文件夹并创建一个文件夹 xff0c 并定义了一个函数 xff0c 但总是遇到WindowsError Error 5 问题 xff0c 经过一番百度 xff0c 是说操作文件权限不够 xff0c
  • Windows下使用WinSW.NET4.exe 设置Nginx的开机自启(新版)

    WinSW NET4 exe 适合X64 xff1b WinSW NET2 exe 适合X86 对应的版本为 xff1a v2 9 0 一 下载地址 https github com winsw winsw releases 下载解压ngi
  • 并查集(Union-Find)算法详解

    并查集 xff08 Union Find xff09 是解决动态连通性问题的一类非常高效的数据结构 本文中 xff0c 我将尽我所能用最简单 xff0c 最清晰的逻辑展示出并查集的构造过程 xff0c 同时还将对其中的关键步骤给出相应的Py
  • apache 编码设置解决

    在windows操作系统上使用IE作为浏览器时 常常会发生这样的问题 xff1a 在浏览使用UTF 8编码的网页时 xff0c 浏览器无法自动侦测 xff08 即没有设定 自动选择 编码格式时 xff09 该页面所用的编码 即使网页已经声明
  • python 字符串相似度判断详解

    1 背景介绍 最近项目中要用到两个字符串相似度的求解算法 xff0c 来矫正ocr文本识别的结果 xff0c 进而提高识别的准确率 xff0c 通过矫正 xff08 相当于模糊查询 xff09 xff0c 识别准确率从65 上升到90 其结
  • 学习使用ffmpeg命令给视频添加一张设计好的背景图片

    学习使用ffmpeg命令给视频添加一张设计好的背景图片 效果如下命令如下 效果如下 未加背景图片之前 xff1a 加上背景图片之后 xff1a 命令如下 ffmpeg loop span class token number 1 span
  • html页面实现使用原生js点击按钮复制文本

    span class token operator lt span span class token operator span Doctype html span class token operator gt span span cla
  • 2.IOC概念及使用xml管理Bean

    1 IOC底层原理 1 1 什么是IOC xff08 1 xff09 控制反转缩写为IOC xff0c 把对象创建和对象之间的调用过程 xff0c 交给Spring管理 xff08 2 xff09 使用IOC目的 xff1a 为了降低耦合度
  • 3. 基于注解方式管理Bean

    1 什么是注解 xff08 1 xff09 注解是代码中的特殊标记 xff0c 格式为 xff1a 64 注解名称 属性名称 61 属性值 属性名称 61 属性值 xff08 2 xff09 注解可以作用在类 方法 属性上面 xff08 3