Spring-2-透彻理解Spring 注解方式创建Bean--IOC

今日目标

学习使用XML配置第三方Bean

掌握纯注解开发定义Bean对象

掌握纯注解开发IOC模式

1. 第三方资源配置管理

说明:以管理DataSource连接池对象为例讲解第三方资源配置管理

1.1 XML管理Druid连接池(第三方Bean)对象【重点】

数据库准备

-- 创建数据库
create database if not exists spring_druid character set utf8;
use spring_druid;
-- 创建表
create table if not exists tbl_account(
    id int primary key auto_increment,
    name varchar(20),
    money double
);
-- 插入数据
insert into tbl_account values(null,'张三',1000);
insert into tbl_account values(null,'李四',1000);
-- 查询所有
select * from tbl_account;

1.2 代码实现XML管理Druid连接池对象(第三方Bean)

【第一步】创建12_1_xml_druid项目

【第二步】Pom.xml添加Druid连接池依赖

 <dependencies>
    <!--导入spring的坐标spring-context,对应版本是5.3.15.RELEASE-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.15</version>
    </dependency>
    <!-- mysql 驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>
    <!--druid包-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.2.18</version>
    </dependency>
    <!-- 导入junit的测试包 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.8.2</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.28</version>
    </dependency>
</dependencies>

【第三步】配置DruidDataSource连接池Bean对象 思考:配置数据库连接参数时,注入驱动类名是用driverClassName还是driver? 在resources下创建Spring的核心配置文件:application.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!--1.创建连接池对象 DruidDataSource
    实际:  dataSource = new DruidDataSource();
  -->
  <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
      <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost:3306/spring_druid"/>
      <property name="username" value="root"/>
      <property name="password" value="root"/>
  </bean>
</beans>

【第四步】在测试类中从IOC容器中获取连接池对象并打印

package com.zbbmeta;

import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class DataSourceTest {

    @Test
    public void test() throws SQLException {

        //目标:从IOC容器中获取德鲁伊连接池对象

        //1.创建IOC容器
        ClassPathXmlApplicationContext ac =
                new ClassPathXmlApplicationContext("application.xml");
        //2.获取连接池对象和数据库连接对象
        DataSource dataSource = ac.getBean(DataSource.class);
        Connection connection = dataSource.getConnection();
        //3.打印对象
        System.out.println("连接池对象:"+dataSource);
        System.out.println("连接象地址:"+connection);

        //4.关闭容器
        ac.close();

    }
}
  • 控制台结果:

现在我们的数据库参数都是写死在xml文件中的,我们讲解druid,是希望大家可以通过这个第三方Bean创建,实现我们举一反三实现其他第三方Bean的创建

思考:根据上面描述我们向如果有一千个第三方Bean需要创建,那么我们把每一个Bean的参数都写死在xml里面?

肯定不是的,所以我们要学习如何将参数数据进行提取出来,每一个Bean的参数单独放一个文件,方便我们查找和修改

1.3 加载properties属性文件【重点】

目的:将数据库的连接参数抽取到一个单独的文件中,与Spring配置文件解耦

1.3.1 properties基本用法

【第一步】在resources下编写jdbc.properties属性文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_druid
username=root
jdbc.password=root

【第二步】在application.xml中开启开启context命名空间,加载jdbc.properties属性文件

<context:property-placeholder location="jdbc.properties" />

【第三步】在配置连接池Bean的地方使用EL表达式获取jdbc.properties属性文件中的值

    <!--1.创建连接池对象 DruidDataSource
      实际:  dataSource = new DruidDataSource();
    -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

【第四步】配置完成之后,运行之前的获取Druid连接池代码

思考:会不会运行成功

不会

严重: create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/spring_druid, errorCode 1045, state 28000
java.sql.SQLException: Access denied for user 'zbb'@'localhost' (using password: YES)

为什么会出现这样的问题?

因为我们加载了系统的环变量

  • 解决1:换一个名称,例如不叫username,叫jdbc.username。(了解)

    【第五步】报错解决方式:在properties标签添加属性

<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>

application.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 https://www.springframework.org/schema/context/spring-context.xsd">

    <!--加载properties文件, ctrl + z 撤销
    ${键}: 取键对应的值
    system-properties-mode="NEVER": 不使用系统的环境变量
    location: 指定properties文件的位置
    location="jdbc.properties,msg.properties": 加载多个properties文件, 使用,逗号分割
    location="*.properties": 加载所有的properties文件,
                如果单元测试加载 src/test/resources里面的所有的properties
                如果main方法运行加载 src/main/resources里面的所有的properties

    location="classpath:*.properties" 加载类路径所有的properties文件, 用在Web应用中
    location="classpath*:*.properties" 加载类路径和依赖的jar中所有的properties文件, 用在Web应用中
    -->
    <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>

    <!--1.创建连接池对象 DruidDataSource
      实际:  dataSource = new DruidDataSource();
    -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
<!--    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_druid"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>-->
</beans>

2.Spring容器

2.1 创建容器

  • 方式一:类路径加载配置文件

ApplicationContext ctx = new ClassPathXmlApplicationContext("application.xml");
  • 方式二:文件路径加载配置文件

ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\application.xml");
  • 加载多个配置文件

ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");

2.2 Spring容器中获取bean对象

  • 方式一:使用bean名称获取

弊端:需要自己强制类型转换

DataSource dataSource = (DataSource)ac.getBean("dataSource");
  • 方式二:使用bean名称获取并指定类型

弊端:推荐使用

DataSource dataSource = ctx.getBean("dataSource", DataSource.class);
  • 方式三:使用bean类型获取

弊端:如果IOC容器中同类型的Bean对象有多个,此处获取会报错

DataSource dataSource = ac.getBean(DataSource.class);

2.3 容器类层次结构

  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载

  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载

  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能

  • ApplicationContext接口常用初始化类
    • ClassPathXmlApplicationContext(常用)

    • FileSystemXmlApplicationContext

    • AnnotationConfigApplicationContext

3. Spring注解开发

3.1 注解开发定义Bean对象【重点】

目的:xml配置Bean对象有些繁琐,使用注解简化Bean对象的定义

3.2代码实现注解开发

【第一步】创建12_2_annotation_ioc

【第二步】Pom.xml添加依赖

<dependencies>
    <!-- spring容器包 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>

    <!-- junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
</dependencies>

【第三步】在application.xml中开启Spring注解包扫描

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

    <!--开启IOC基础包扫描:目的是去到指定包下扫描IOC注解进行IOC功能使用
        spring框架优势:可插拔
            白话:使用这个功能就插入,不用这个功能就拔掉
            那么这个注解扫描的功能就符合可插拔的特性,配置上IOC注解扫描就进行扫描,不配置不会做扫描
    -->
    <context:component-scan base-package="com.zbbmeta" />
</beans>

【第四步】在类上使用@Component注解定义Bean。

public interface StudentDao {
    /**
     * 添加学生
     */
    void save();
}
package com.zbbmeta.dao.impl;

import com.zbbmeta.dao.StudentDao;
import org.springframework.stereotype.Component;

/**
 * @Component
 * 作用:相当于<bean>标签,用于创建IOC创建对象并加入IOC容器
 * 使用方法2种格式:
 *    @Component 创建对象并且设置对象别名为类名小驼峰,
 *              与<bean class="com.zbbmeta.dao.impl.StudentDaoImpl" id="studentDaoImpl"></bean>功能一样
 *    @Component("自定义别名") 创建对象并且设置别名加入IOC容器
 *
 *   IOC创建对象注解还有衍生的3个
 *      @Controller 定义表现层的对象
 *      @Service 定义业务层的对象
 *      @Repository 定义数据访问层的对象
 *      说明:这3个功能与@Component一样,只是为了增加可读性
 *            @Component适合在工具类的上面使用创建对象
 *
 */
@Component
public class StudentDaoImpl implements StudentDao {
    @Override
    public void save() {
        System.out.println("DAO: 添加学生信息到数据库...");
    }
}

补充说明:如果@Component注解没有使用参数指定Bean的名称,那么类名首字母小写就是Bean在IOC容器中的默认名称。例如:StudentDaoImpl对象在IOC容器中的名称是studentDaoImpl。

【第五步】在测试类中获取Bean对象

package com.zbbmeta;

import com.zbbmeta.dao.StudentDao;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StudentDaoAnnotationTest {
    //目标:获取注解创建的Bean对象
    @Test
    public void testAnnotation(){
        //1.根据配置文件application.xml创建IOC容器
        ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
        //2.从IOC容器里面获取id="studentDao"对象
        StudentDao studentDao = (StudentDao) ac.getBean("studentDaoImpl");
        System.out.println(studentDao);
    }
}

运行结果

com.zbbmeta.dao.impl.StudentDaoImpl@7d64e326

注意:每一个人获取的地址是不一样的

3.3 @Component三个衍生注解

说明:加粗的注解为常用注解

  • Spring提供**@Component**注解的三个衍生注解
    • **@Controller**:用于表现层bean定义

    • **@Service**:用于业务层bean定义

    • @Repository:用于数据层bean定义

说明:这3个功能与@Component一样,只是为了增加可读性

@Component适合在工具类的上面使用创建对象

@Repository
public class StudentDaoImpl implements StudentDao {
}

我们上面代码虽然类中都使用注解,但是我们还是存在xml,说明现在spring开发还不是完全的注解开发,可以称为半注解开发

4 Spring纯注解开发模式IOC【重点】

问题导入

思考:配置类上使用什么注解进行Spring注解包扫描替代xml中的配置?

4.1 纯注解开发模式介绍

  • Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道

  • Java类代替Spring核心配置文件

  • @Configuration注解用于设定当前类为配置类

  • @ComponentScan注解用于设定扫描路径

注意:此注解只能添加一次,多个数据请用数组格式

@ComponentScan({com.zbbmeta.service","com.zbbmeta.dao"})
  • 读取Spring注解配置类初始化容器对象

//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

4.2 代码演示

【第零步】创建12_3_full_annotation_ioc项目并添加依赖

依赖和上一个项目相同

【第一步】定义配置类代替配置文件

@Configuration // 指定这个类为配置类,替代application.xml
@ComponentScan("com.zbbmeta")//代替<context:component-scan base-package="com.zbbmeta" />
//设置bean扫描路径,多个路径书写为字符串数组格式
//@ComponentScan({com.zbbmeta.service","com.zbbmeta.dao"})
public class SpringConfig {
}

【第二步】在测试类中加载配置类,获取Bean对象并使用

package com.zbbmeta;

import com.zbbmeta.config.SpringConfig;
import com.zbbmeta.service.StudentService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class StudentDaoAnnotationTest {
    //目标:获取注解创建的Bean对象
    @Test
    public void testAnnotation(){
        //1.AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        StudentService studentService = (StudentService) ctx.getBean("studentServiceImpl");
        System.out.println(studentService);
        //按类型获取bean
        StudentService studentService2 = ctx.getBean(StudentService.class);
        System.out.println(studentService2);
    }
}

4.3 注解开发Bean作用范围和生命周期管理

问题导入

思考:在类上使用什么注解定义Bean的作用范围?

4.3.1 bean作用范围注解配置

  • 使用@Scope定义bean作用范围

@Component
@Scope("singleton")
public class StudentUtils {
}

4.3.2 bean生命周期注解配置

  • 使用@PostConstruct、@PreDestroy定义bean生命周期

package com.zbbmeta.utils;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;


@Component
@Scope("singleton")
public class StudentUtil {

    public StudentUtil() {
        System.out.println("Student constructor ...");
    }
    @PostConstruct
    public void init(){
        System.out.println("Student init ...");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("Student destory ...");
    }
}

注意:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk9开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>
  • 测试类

@Test
public void testStudentUtil(){
    //1.AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    //按类型获取bean
    StudentUtil studentUtil = ctx.getBean(StudentUtil.class);
    System.out.println(studentUtil);
    //关闭容器
    ctx.close();
}

测试结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/70525.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基础小项目

今天给大家写一期特别基础的Python小项目&#xff0c;欢迎大家支持&#xff0c;并给出自己的完善修改 &#xff08;因为我写的都是很基础的&#xff0c;运行速率不是很好的 目录 1. 地铁票价题目程序源码运行截图 2. 购物车题目程序源码运行截图 3. 名片管理器题目程序源码运行…

opencv实战项目 实现手势跟踪并返回位置信息(封装调用)

OpenCV 是一个基于 Apache2.0 许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。 需要提前准备opencv 和 mediapipe库 pip --default-timeout5000 install -i https://pypi.tuna.tsi…

nodejs+vue+elementui社区流浪猫狗救助救援网站_4a4i2

基于此背景&#xff0c;本研究结合管理员即时发布流浪猫狗救助救援信息与用户的需求&#xff0c;设计并实现了流浪猫狗救助救援网站。系统采用B/S架构&#xff0c;java语言作为主要开发语言&#xff0c;MySQL技术创建和管理数据库。系统主要分为管理员和用户两大功能模块。通过…

【Linux取经路】进程的奥秘

文章目录 1、什么是进程&#xff1f;1.1 自己写一个进程 2、操作系统如何管理进程&#xff1f;2.1 描述进程-PCB2.2 组织进程2.3 深入理解进程 3、Linux环境下的进程3.1 task_struct3.2 task_struct内容分类3.3 组织进程3.4 查看进程属性 4、结语 1、什么是进程&#xff1f; 在…

FreeRTOS

FreeRTOS官网&#xff1a;www.freertos.org 调度 实时操作系统 特点&#xff1a;如果有一个任务需要执行&#xff0c;实时操作系统会马上&#xff08;在较短时间内&#xff09;执行该任务&#xff0c;不会有较长的延时。这种特性保证了各个任务的及时执行。 实现方式&#…

web前端之CSS操作

文章目录 一、CSS操作1.1 html元素的style属性1.2 元素节点的style属性1.3 cssText属性 二、事件2.1 事件处理程序2.1.1 html事件2.1.2 DOM0事件&#xff08;适合单个事件&#xff09;2.1.3 DOM2事件&#xff08;适合多个事件&#xff09; 2.2 事件之鼠标事件2.3 事件之Event事…

详解Kafka分区机制原理|Kafka 系列 二

Kafka 系列第二篇&#xff0c;详解分区机制原理。为了不错过更新&#xff0c;请大家将本号“设为星标”。 点击上方“后端开发技术”&#xff0c;选择“设为星标” &#xff0c;优质资源及时送达 上一篇文章介绍了 Kafka 的基本概念和术语&#xff0c;里面有个概念是 分区(Part…

计算机竞赛 opencv python 深度学习垃圾图像分类系统

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; opencv python 深度学习垃圾分类系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 这是一个较为新颖的竞…

pytest结合 allure 打标记之的详细使用

前言 前面我们提到使用allure 可以生成漂亮的测试报告&#xff0c;下面就Allure 标记我们做详细介绍。 allure 标记 包含&#xff1a;epic&#xff0c;feature, story, title, testcase, issue, description, step, serverity, link, attachment 常用的标记 allure.feature…

Mysql中如果建立了索引,索引所占的空间随着数据量增长而变大,这样无论写入还是查询,性能都会有所下降,怎么处理?

索引所占空间的增长确实会对MySQL数据库的写入性能和查询性能造成影响&#xff0c;这主要是由于索引数据过多时会导致磁盘I/O操作变得非常频繁&#xff0c;从而使性能下降。为此&#xff0c;可以采取以下几种方式来减缓这种影响&#xff1a; 1. 限制索引的大小&#xff1a;可以…

PHP8定义字符串的方法-PHP8知识详解

字符串&#xff0c;顾名思义&#xff0c;就是将一堆字符串联在一起。字符串简单的定义方法是使用英文单引号&#xff08; &#xff09;或英文双引号&#xff08;" "&#xff09;包含字符。另外&#xff0c;还可以使用定界符定义字符串。本文还介绍了字符串的连接符。…

数据结构和算法三(排序)

列表排序 排序类型&#xff1a; 一、冒泡排序&#xff1a; 屏幕录制2023-07-25 13.05.12 def bubble_sort(li):exchangeFalseif len(li)<1:return lifor i in range(len(li)-1):for j in range(len(li)-i-1):if li[j]>li[j1]:li[j],li[j1]li[j1],li[j]print(li)exchangeT…

mac harbor的安装

harbor的安装 为什么要整这个呢&#xff0c;因为我在学习k8s&#xff0c;但是需要一个自己的镜像仓库。于是&#xff0c;最开始想到的就是在本地直接部署一个&#xff0c;还比较安全、快速。 直接下载了官方的项目&#xff0c;运行脚本发现出了异常&#xff0c;这种异常我已经…

项目知识点记录

1.使用druid连接池 使用properties配置文件&#xff1a; driverClassName com.mysql.cj.jdbc.Driver url jdbc:mysql://localhost:3306/book?useSSLtrue&setUnicodetrue&charsetEncodingUTF-8&serverTimezoneGMT%2B8 username root password 123456 #初始化链接数…

LiveNVR监控流媒体Onvif/RTSP功能-视频流水印如何叠加视频水印叠加动态图片叠加视频流时间示例

LiveNVR视频流水印如何叠加视频水印叠加动态图片叠加视频流时间示例 1、介绍2、摄像头OSD设置水印3、前端页面叠加4、视频流水印4.1、图片水印示例4.2、时间戳水印示例 5、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 1、介绍 监控视频平台播放视频监控的时候&#xff0c;除了满足正…

SpringMVC的架构有什么优势?——控制器(三)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

CentOS 7中,配置了Oracle jdk,但是使用java -version验证时,出现的版本是OpenJDK,如何解决?

1.首先&#xff0c;检查已安装的jdk版本 sudo yum list installed | grep java2.移除、卸载圈红的系统自带的openjdk sudo yum remove java-1.7.0-openjdk.x86_64 sudo yum remove java-1.7.0-openjdk-headless.x86_64 sudo yum remove java-1.8.0-openjdk.x86_64 sudo yum r…

STM32单片机蓝牙APP宠物自动喂食器定时语音提醒喂食系统设计

实践制作DIY- GC00162---蓝牙APP宠物自动喂食器 一、功能说明&#xff1a; 基于STM32单片机设计---蓝牙APP宠物自动喂食器 二、功能说明&#xff1a; STM32F103C系列最小系统板LCD1602显示器DS1302时钟模块5个按键语音播报模块ULN2003步进电机模块LED灯板HC-05蓝牙模块&#x…

XML方式AOP快速入门XML方式AOP配置详解

目录 1.XML方式AOP快速入门 1&#xff1a;导入AOP相关坐标 2&#xff1a;准备目标类&#xff0c;准备增强类&#xff0c;并配置给Spring管理 3&#xff1a;配置切点表达式&#xff08;那些方法要被增强&#xff09; 4&#xff1a;配置织入&#xff08;切点被哪些方法增强&…

C++初阶语法——类和对象

前言&#xff1a;C语言中的结构体&#xff0c;在C有着更高位替代者——类。而类的实例化叫做对象。 本篇文章不定期更新扩展后续内容。 目录 一.面向过程和面向对象初步认识二.类1.C中的结构体2.类的定义类的两种定义方式 3.类的访问限定符及封装访问限定符说明 4.类的实例化对…