spring框架(ioc控制反转 aop面向切面编程)

news2024/9/24 19:22:48

目录

服务端三层开发:

 spring框架(ioc控制反转 aop面向切面编程)

1、Spring框架的优点

什么是事物?

2、Spring的IOC核心技术

什么是ioc?

代码举例:(详细流程见笔记)

**applicationContext.xml配置文件中标签

3、DI注入 (DI注入是实现ioc的基础)

DI注入的方式:

属性的set方法注入值

属性构造方法方式注入值

数组,集合(List,Set,Map),Properties等的注入

4、多配置文件方式

5、使用spring框架进行程序开发:

spring框架开发示例:

代码操作:

创建mavenJava工程,导入开发的jar包依赖:

创建数据库表格:

编写实体类,实现序列号与反序列化接口

编写持久层dao层

编写业务层接口和实现类:

编写配置文件:

编写测试程序:


服务端三层开发:

表现层 controller 用框架springMVC

业务层 service 用框架Spring

持久层 mapper dao 操作数据库 用框架Mybatis

Spring+springMVC+Mybatis开发称为SSM架构开发。

客户端可以看做用户浏览器,它发送请求给表现层,最后接受表现层的请求

表现层接收前端传过来的请求,并调用业务层进行业务逻辑处理;业务层在业务处理时,调用持久层对数据库进行操作,让将返回的数据返回给表现层。

持久层主要面向数据库操作数据库等。

 spring框架(ioc控制反转 aop面向切面编程)

实现ioc 可采用配置文件形式、半注解形式、注解形式, aop也是一样

Spring解决的是业务层和其他各层的松耦合问题

耦合度:模块或对象之间相互依赖的程度,即一个模块或对象对另一个模块或对象的依赖程度。

耦合度越高,表示一个模块或对象对其他模块或对象的依赖程度越紧密,这样会导致系统的可维护性、可扩展性和可复用性变差,增加系统的复杂度,降低系统的稳定性。

而耦合度越低,表示一个模块或对象对其他模块或对象的依赖程度越小,模块之间的独立性越高,这样会有利于系统的维护、扩展和重用,提高系统的可靠性和可维护性。

1、Spring框架的优点

1.方便解耦,简化开发,Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理。IOC的作用。 (无需自己new新对象,把这个创建的权力交给spring去管理,降低耦合度)

2.AOP编程的支持,Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能。(可扩展性)

3.声明式事务的支持,只需要通过配置就可以完成对事务的管理,而无需手动编程。

4.方便程序的测试,Spring对Junit4支持,可以通过注解方便的测试Spring程序。

5.方便集成各种优秀框架,Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts2、Hibernate、MyBatis、Quartz等)的直接支持。

6.降低JavaEE API的使用难度,Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低。比如简化jdbc的步骤:

什么是事物?

事物是最小的逻辑单元,不可分割。

举例:张三给李四转账500,张三账号-500,李四账户+500,两件事同时操作不可分割,可将两件事看做一个事物 要么一起成功要么一起失败

执行此逻辑之前就要进行事物管理开启事物,出现错误时 回滚事务,没有问题时最终确认提交事物。

2、Spring的IOC核心技术

什么是ioc?

ioc就是控制反转,将对象的创建权力反转给Spring框架!!降低程序耦合度,让Spring的工厂读取配置文件。

代码举例:(详细流程见笔记)

可以先创建一个接口和一个实现类,实现类里写一个简单的输出方法。用于测试IOC创建新对象调用其方法。

要想将对象的创建权力反转给Spring框架,就要编写Spring核心的配置文件(里面有约束信息),创建applicationContext.xml(默认名称)的配置文件。

这里的bean标签作用将某一个类交给spring去管理,创建对象(ioc的作用)

如何使用 这个交给spring工厂的类

/**
 * 测试方法
 * IOC入门程序
 */
@Test
public void run(){
    // 使用Spring的工厂,读取配置文件,拿到配置信息
    ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    // 通过工厂,利用bean对象的id值  获得类对象
    UserService userService = (UserService) ac.getBean("userService");
    //调用方法
    us.hello();
}

总结:并没有创建新对象,而是用spring的工厂创建对象

注意:用new 的方式为同一个类创建对象,创建的是不一样的对象;而用spring工厂为同一个类创建对象,在默认情况下是单例模式 (创建的是一个对象),可提高提高内存效率。

**applicationContext.xml配置文件中标签

3、DI注入 (DI注入是实现ioc的基础)

 DI:依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中!!

DI注入的方式:

属性的set方法注入值

在实体类中编写属性,(一定)提供该属性对应的set方法(因为框架底层是通过属性的set方法进行注入的),编写配置文件bean标签 完成属性值的注入

属性构造方法方式注入值

这个要注意的是:实体类里面一定要有有参构造器(框架底层会使用有参构造器进行注入)

数组,集合(List,Set,Map),Properties等的注入

前两种注入方式用的比较多,是主要注入方式。

4、多配置文件方式

在resource目录下创建了两个配置文件

那么如何加载这两个配置文件的内容呢?

1、主配置文件中包含其他的配置文件:import resource="applicationContext2.xml"/>​

2、工厂创建的时候直接加载多个配置文件:

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");

5、使用spring框架进行程序开发:

连接池:

使用jdbc连接数据库,每一次都会建立一个新连接然后销毁连接

把与数据库建立的连接放到连接池里,每次要用就拿一个出来,用完不销毁而是重新放到连接池中,这样省去了创建和销毁连接的时间,可提高性能

序列化和反序列化:

数据在网络上传递是通过io流,实现序列化之后可以解析为字节流,然后传输完再组装回来

序列化:把Java对象转换为字节序列。

反序列化:把字节序列恢复为原先的Java对象

要知道: 创建一个对象,就让他实现Serializable接口,保证其能序列化与反序列化

spring框架开发示例:

1. 需求:编写service和dao的类,演示代码

2. 技术选择:持久层使用原始的JDBC的程序,连接池选择的是Druid连接池。通过DI注入的方式,将dao层和service层的实现类注入,交给spring去管理,然后在测试类里面用spring工厂来创建类的实例对象,并调用service层实现类的方法(service层实现类调用dao层接口方法,再用dao层实现类进行数据库查询)来进行对数据库数据的查询。

如果还想再优化,可以将dataSource也进行DI注入(在配置文件里写好dataSource的驱动加载),无需在AccountDaoImpl类里面new一个dataSource进行驱动加载

代码操作:
创建mavenJava工程,导入开发的jar包依赖:
<dependencies>
    <!--通过maven传递依赖,导入依赖的jar包-->
    <!--spring核心依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>

    <!--日志信息-->
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>

    <!--junit用于测试的-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>

    <!--spring整合测试类的-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.2.RELEASE</version>
        <scope>test</scope>
    </dependency>

    <!--连接池-->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.10</version>
    </dependency>

    <!--mysql数据库驱动包-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</version>
    </dependency>
</dependencies>
创建数据库表格:

编写实体类,实现序列号与反序列化接口
/**
 * 实体类
 * 账户表的实体类
 * 序列化
 * 反序列化
 */
public class Account implements Serializable{

    //id
    private Integer id;
    //名称
    private String name;
    //钱 金额
    private Double money;
    public Account() {
    }
    public Account(Integer id, String name, Double money) {
        this.id = id;
        this.name = name;
        this.money = money;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Double getMoney() {
        return money;
    }
    public void setMoney(Double money) {
        this.money = money;
    }
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

在做项目写实现业务的类的时候,为什么先要写一个接口?

1、耦合度低

2、面向接口开发,可维护性可扩展性强

编写持久层dao层

接口:

/**
 * 持久层接口
 * 面向接口开发
 */
public interface AccountDao {
    public List<Account> findAll() throws SQLException;
}

实现类:


/**
 * 持久层接口实现类
 * 面向接口开发
 */
public class AccountDaoImpl implements AccountDao{

    //使用DI注入,注入dataSource
    private DataSource dataSource;

    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    /**
     * 使用jdbc操作数据库
     * @return
     */
//    @Override
    public List<Account> findAll() throws SQLException {
        List<Account> list=new ArrayList<Account>();
        ResultSet resultSet =null;
        PreparedStatement stmt = null;
        Connection conn= null;
        try {
            //1.加载驱动 在配置文件里加载好了,可DI注入后直接调用
            //2.获取连接
            conn=dataSource.getConnection();
            //3.编写sql
            String sql = "select * from account";
            //4.预编译sql
            stmt = conn.prepareStatement(sql);
            //5.设置值  这里是查询操作所以不用设置值
            //6.执行sql拿到结果集
            resultSet = stmt.executeQuery();
            while (resultSet.next()) {
                Account account = new Account();
                account.setId(resultSet.getInt("id"));
                account.setName(resultSet.getString("name"));
                account.setMoney(resultSet.getDouble("money"));
                list.add(account);
            }
            //7.遍历结果集关闭资源

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            resultSet.close();
            stmt.close();
            //关闭连接  是放回连接池 而不是销毁
            conn.close();
        }
        return list;
    }
}
编写业务层接口和实现类:
/**
 * 查询所有账户信息的业务层接口
 */
public interface AccountService {
    //业务层查询所有账户
    public List<Account> findAll() throws SQLException;
}
/**
 * 业务层实现类
 * 实现查询所有账户
 */
public class AccountServiceImpl implements AccountService{
    private AccountDao accountDao;
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
//    @Override
    public List<Account> findAll() throws SQLException {
        return accountDao.findAll();//这里调用accountDao接口的findAll查询方法
    }
}
编写配置文件:
<?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">
                 
    <!--注入service层实现类-->
    <bean id="accountServie" class="com.qcby.service.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"/>
    </bean>
   <!--注入dao层实现类-->
    <bean id="accountDao" class="com.qcby.dao.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"/>
    </bean>

<!--注入dataSource,第三方提供的连接池类-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc///spring_db?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimezone=UTC&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
    
</beans>
编写测试程序:
/**
 * 测试方法
 * spring开发程序
 */
@Test
public void run2() throws SQLException {
    // 使用Spring的工厂
    ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
    AccountService accountServie = (AccountService) ac.getBean("accountServie");
    List<Account> accountList = accountServie.findAll();
    for (Account account : accountList) {
        System.out.println(account);
    }
}

运行测试类,就拿到了数据库的数据:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一些简单的基本知识(与C基本一致)

一、注释 1.单行注释&#xff1a;//&#xff08;快捷键&#xff1a;ctrlshift&#xff1f;&#xff0c;可以选择多行&#xff09; 2.多行注释&#xff1a;/* 文本 */ 二、变量 变量的作用是给一段内存空间起名&#xff0c;方便操作内存中的数据。 通过赋予某数据的…

肯德基蛋挞咖啡?品牌为何热衷于研发“奇葩”新品

想喝蛋挞的风还是吹到了咖啡这里... 是的&#xff0c;它来了&#xff0c;它带着新品走来了。前不久&#xff0c;肯德基旗下的肯悦咖啡推出了一款“蛋挞dirty”&#xff0c;就是把除去蛋挞的芯&#xff0c;留下蛋挞皮皮献给咖啡&#xff0c;成功变成了可以吃的咖啡或者说是可以…

Java面试题--JVM大厂篇之深入解析JVM中的Serial GC:工作原理与代际区别

目录 引言&#xff1a; 正文&#xff1a; 一、Serial GC工作原理 年轻代垃圾回收&#xff08;Minor GC&#xff09;&#xff1a; 老年代垃圾回收&#xff08;Major GC或Full GC&#xff09;&#xff1a; 二、年轻代和老年代的区别 年轻代&#xff08;Young Generation&a…

Java 中的正则表达式

转义字符由反斜杠\x组成&#xff0c;用于实现特殊功能当想取消这些特殊功能时可以在前面加上反斜杠\ 例如在Java中当\出现时是转义字符的一部分&#xff0c;具有特殊意义&#xff0c;前面加一个反斜可以取消其特殊意义&#xff0c;表示1个普通的反斜杠\&#xff0c;\\\\表示2个…

Java从入门到精通(第4版)中文电子版

前言 针对编程语言JAVA相关知识进行了精密的讲解&#xff0c;全册分为28章&#xff0c;含基础知识、核心知识、高级应用3大核心模块&#xff0c;具体细分又包括初识Java&#xff0c;类的高级特性&#xff0c;流程控制&#xff0c;字符串&#xff0c;数组&#xff0c;数据库操作…

团队提效探索:市场上最好的10款项目工单管理工具对比

本文将分享2024年值得关注的10款项目工单管理系统&#xff1a;PingCode、Worktile、蓝凌OA、禅道、泛微E-office、Teambition、monday.com、Basecamp、ProofHub、Wrike。 你是否曾经因为项目进度混乱而感到头疼&#xff0c;或是在处理大量任务时不知所措&#xff1f;在项目管理…

探索编程世界的乐趣:《C++青少年趣味编程108例》

&#x1f482; 个人网站:【 摸鱼游戏】【网址导航】【神级代码资源网站】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

TinyVue v3.17.0 正式发布,推出了一款基于 Quill 2.0 的富文本编辑器,功能强大、开箱即用!

本文由体验技术团队Kagol老师原创~ 我们非常高兴地宣布&#xff0c;2024年6月26日&#xff0c;TinyVue 发布了 v3.17.0 &#x1f389;。 TinyVue 每次大版本发布&#xff0c;都会给大家带来一些实用的新特性&#xff0c;上一个版本我们重构了 chart-core&#xff0c;新增 Circ…

算法2--贪心算法

1.老鼠和猫的交易 小老鼠准备了M磅的猫粮&#xff0c;准备去和看守仓库的猫做交易&#xff0c;因为仓库里有小老鼠喜欢吃的五香豆。 仓库有N个房间&#xff1b; 第i个房间有 J[i] 磅的五香豆&#xff0c;并且需要用 F[i] 磅的猫粮去交换&#xff1b; 老鼠不必交换该房间所有的五…

笔记 5 :linux 0.11 注释,函数 copy_mem() , copy_process () , 中断函数 int 80H 的代码框架

&#xff08;38&#xff09;接着介绍一个创建进程时的重要的函数 copy_mem&#xff08;&#xff09; 函数&#xff1a; &#xff08;39&#xff09; 分析另一个关于 fork&#xff08;&#xff09; 的重要的函数 copy_process&#xff08;&#xff09;&#xff0c;与李忠老师的操…

暑期-大数据人工智能学习-在线实习项目

这个暑期 默默努力一把 悄悄惊艳所有人 在线企业项目试岗实训 助你突破固有思维模式&#xff0c;伴你进阶成长

MySQL索引特性(下)

目录 索引的理解 理解单个Page 理解多个Page 页目录 单页情况 多页情况 复盘一下 聚簇索引VS非聚簇索引 区别 索引操作 主键索引 唯一索引的创建 普通索引的创建 查询索引 删除索引 索引创建原则 索引的理解 理解单个Page MySQL 中要管理很多数据表文件&#xff0c;而…

阿里云ECS跨区域迁移,利用老操作系统作为新服务操作系统

由于特殊原因或者数据备份需要迁移ecs服务器 1.老服务快照 选择ecs实例&#xff0c;点开实例 进入云盘 https://ecs.console.aliyun.com/disk 在云盘上点击建立快照 2.准备oss同源 购买oss 存储&#xff0c;用于临时备份 https://oss.console.aliyun.com/bucket/ 记得必…

Spring如何进行动态注册Bean

在Spring框架中&#xff0c;Bean是应用程序的核心组成部分&#xff0c;而BeanDefinition则是这些Bean的元数据表示。随着应用程序的复杂性增加&#xff0c;我们可能需要更灵活地定义和注册Bean。Spring框架提供了几个扩展点&#xff0c;允许我们以编程方式影响Bean的创建和定义…

Window中 Redis下载安装

Redis7.2.3连接&#xff1a; 我用夸克网盘分享了「redis-windows-7.2.3.zip」&#xff0c;点击链接即可保存。打开「夸克APP」&#xff0c;无需下载在线播放视频&#xff0c;畅享原画5倍速&#xff0c;支持电视投屏。 链接&#xff1a;https://pan.quark.cn/s/4dfb0497707a 在安…

Uniapp基础篇(持续更新)

1. Uni-app常用内置组件 view 视图容器 scroll-view 可滚动视图区域&#xff0c;用于区域滚动。需注意在webview渲染的页面中&#xff0c;区域滚动的性能不及页面滚动。 swiper 滑块视图容器。一般用于左右滑动或上下滑动&#xff0c;比如banner轮播图。 image uniapp官方iam…

封装网络请求 鸿蒙APP HarmonyOS ArkTS

一、效果展示 通过在页面直接调用 userLogin(params) 方法&#xff0c;获取登录令牌 二、申请网络权限 访问网络时候首先需要申请网络权限&#xff0c;需要修改 src/main 目录下的 module.json5 文件&#xff0c;加入 requestPermissions 属性&#xff0c;详见官方文档 【声明权…

Flink底层原理解析:案例解析(第37天)

系列文章目录 一、flink架构 二、Flink底层原理解析 三、Flink应用场景解析 四、fink入门案例解析 文章目录 系列文章目录前言一、flink架构1. 作业管理器&#xff08;JobManager&#xff09;2. 资源管理器&#xff08;ResourceManager&#xff09;3. 任务管理器&#xff08;Ta…

Hadoop安装报错

报错&#xff1a;ERROR 2023-03-09 21:33:00,178 NetUtil.py:97 - SSLError: Failed to connect. Please check openssl library versions. 解决方案: 在安装失败得客户端执行 编辑 /etc/python/cert-verification.cfg 配置文件&#xff0c;将 [https] 节的 verify 项 设为禁用…

【教学类-67-02】20240716毛毛虫ABB排序

背景需求&#xff1a; 【教学类-67-01】20240715毛毛虫AB排序-CSDN博客文章浏览阅读584次&#xff0c;点赞16次&#xff0c;收藏6次。【教学类-67-01】20240715毛毛虫AB排序https://blog.csdn.net/reasonsummer/article/details/140443310 在AB排序基础上&#xff0c;继续制作…