javaee之Spring4

news2025/1/17 8:53:19

之前说到AccountDao需要继承JdbcDaoSupport这个类,那么现在来看一下这个类的内容

JdbcDaoSupport.java

package com.itheima.dao.impl;

/**
 * 此类用于抽取dao中的重复代码
*/

public class JdbcDaoSupport {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }


    public void setDataSource(DataSource dataSource) {
        if(jdbcTemplate == null){
            jdbcTemplate = createJdbcTemplate(dataSource);
        }
    }

    private JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }
}
 

 

 

看一下bean.xml的配置

那么这个bean.xml还可以这样配置,既然有JbdcTemplate对象还有DataSource对象,那么就也可以注入DataSource去创建一个JdbcTemplate对象

 

 

 为什么说要这样配置呢,就是因为在我们以后的开发中,不止有一个Dao文件,可能会有很多的Dao文件,那么这些文件,最后都要去操作数据库,也就是说,这些文件都必须有一个JdbcTemplate对象和数据源,注意这里的数据源是封装到JdbcTemplate模板上面的

实际业务操作

但是你能想到的事儿,Spring也能做到,那么Spring怎么来做的

换句话说,Spring内部也是提供了那么一个JdbcSupport来供我们使用,这样也就是Spring给我们提供的一个jar包,内部封装好了JdbcTemplate和DataSource对象,我们就可以通过Bean.xml来进行配置,但是注解去配置不行,因为Spring给我们提供的jar是只读的

Spring中的事务控制

1.之前做了一个银行转账事务,现在我们通过xml来配置一下这个事务的实现过程

现在的要求就是,我们不要下面这个文件,也就是说我们不需要这个代理工厂去给我们生产一个代理对象了

BeanFactory.java

package com.pxx.factory;

import com.pxx.service.IAccountService;
import com.pxx.utils.TransactionManager;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BeanFactory {
    private IAccountService accountService;

    private TransactionManager txManager;

    public void setTxManager(TransactionManager txManager) {
        this.txManager = txManager;
    }


    public final void setAccountService(IAccountService accountService) {
        this.accountService = accountService;
    }

    /**
     * 把service里面的方法全部进行增强
     */
    public IAccountService getInstance() {

        return (IAccountService)Enhancer.create(accountService.getClass(), new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //这里面就是具体增强代码
                try {
                    System.out.println("开始增强了");
                    Object value = null;
                    //主要是我们需要在执行一个方法前后添加事务控制
                    txManager.beginTransaction();//开启事务
                    value = method.invoke(accountService,args);//有啥参数就拿过来匹配
                    //提交事务
                    txManager.commit();
                    System.out.println("增强结束");
                    return value;
                } catch (Exception e) {
                    //有异常出现,把数据进行回滚
                    txManager.rollback();;
                    System.out.println("出现饿了异常");
                    throw new RuntimeException(e);
                } finally {
                    //释放连接
                    txManager.release();
                }
            }
        });

    }
}

那么这个文件删除之后

 在bean.xml文件中,也会报错

 现在要求就是通过配置Spring,调用自己的Servcie来完成代码的编写工作

既然我们要通过AOP来进行一个事务控制,就必修在xml头部引入AOP的约束

 配好了之后,检查一下pom.xml是否有如下这个依赖

这个依赖没有,是不能去解析切入点表达式的

 正常测试没问题,钱不会少

下面把上面的过程全部改成注解的AOP实现以及问题分析

既然要用到注解配置,那么bean.xml约束就要从新去修改一下,要引入context部分的内容

 

然后我们去修改service层

 

 下面我们去配置一下Dao层的注解

 注意QueryRunner这个类里面又有一个数据源的依赖,但是这个数据源又是依赖于配置文件的所以下面的不能删除

 下面去配置一下ConnectionUtils这个类

 下面我们去配置一下事务管理器

package com.pxx.utils;

import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
 */
@Component("txManger")
@Aspect
public class TransactionManager {

    //引入一个连接对象
    @Autowired
    private ConnectionUtils connectionUtils;



   /* //我们要采用set注入,必须添加一个set方法
    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }*/

   //配置一个切入点
    @Pointcut("execution(* com.pxx.service.impl.*.*(..))")
    private void pt1(){}

    //开启事务
    @Before("pt1()")
    public void beginTransaction() {
        try {
            connectionUtils.getThreadConnection().setAutoCommit(false);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 提交事务
     */
    @AfterReturning("pt1()")
    public  void commit(){
        try {
            System.out.println("事务提交");
            connectionUtils.getThreadConnection().commit();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务
     */
    @AfterThrowing("pt1()")
    public  void rollback(){
        try {
            System.out.println("事务回滚");
            connectionUtils.getThreadConnection().rollback();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 释放连接
     */
    @After("pt1()")
    public  void release(){
        try {
            connectionUtils.getThreadConnection().close();//还回连接池中
            connectionUtils.removeConnection();
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

 配置bean.xml对事务的支持

 

测试一下代码

首先看一下正常转账能不能行

按照上面单独这种配置,会出现这种报错

 这里涉及到一个问题,Spring的通知执行流程就是:

那如果我们要解决这个问题,我们就去配置一个环绕通知,让每一个通知明确知道在何时何地的为我们服务

 

完整代码

 TransactionManager.java
package com.pxx.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 *
 * 和事务管理相关的工具类,它包含了,开启事务,提交事务,回滚事务和释放连接
 */
@Component("txManger")
@Aspect
public class TransactionManager {

    //引入一个连接对象
    @Autowired
    private ConnectionUtils connectionUtils;



   /* //我们要采用set注入,必须添加一个set方法
    public void setConnectionUtils(ConnectionUtils connectionUtils) {
        this.connectionUtils = connectionUtils;
    }*/

   //配置一个切入点
    @Pointcut("execution(* com.pxx.service.impl.*.*(..))")
    private void pt1(){}

    //开启事务
   // @Before("pt1()")
    public void beginTransaction() {
        try {
            System.out.println("事务开启");
            connectionUtils.getThreadConnection().setAutoCommit(false);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 提交事务
     */
   // @AfterReturning("pt1()")
    public  void commit(){
        try {
            System.out.println("事务提交");
            connectionUtils.getThreadConnection().commit();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 回滚事务
     */
   // @AfterThrowing("pt1()")
    public  void rollback(){
        try {
            System.out.println("事务回滚");
            connectionUtils.getThreadConnection().rollback();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 释放连接
     */
   // @After("pt1()")
    public  void release(){
        try {
            System.out.println("事务关闭");
            connectionUtils.getThreadConnection().close();//还回连接池中
            connectionUtils.removeConnection();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Around("pt1()")
    public Object aroundAdvice(ProceedingJoinPoint pjp){
        Object rtValue = null;
        try {
            //1.获取参数
            Object[] args = pjp.getArgs();
            //2.开启事务
            this.beginTransaction();
            //3.执行方法
            rtValue = pjp.proceed(args);
            //4.提交事务
            this.commit();

            //返回结果
            return  rtValue;

        }catch (Throwable e){
            //5.回滚事务
            this.rollback();
            throw new RuntimeException(e);
        }finally {
            //6.释放资源
            this.release();
        }
    }
}

这样就是正常执行业务流程 

 Spring中事务控制的一组API

 

 

 

 

 

 

 

 

基于 XML 的声明式事务控制(配置方式) 

 先来看一下AccountDaoImpl

 

 看service层

 

 这个里面还没有配任何事务,下面去看一下测试方法

测试一下这个方法

 

 

 下面来说一下Spring基于xml的声明式事务控制

 spring中基于XML的声明式事务控制配置步骤
        1、配置事务管理器


        2、配置事务的通知
                此时我们需要导入事务的约束 tx名称空间和约束,同时也需要aop的

                
           

 

    使用tx:advice标签配置事务通知
                    属性:
                        id:给事务通知起一个唯一标识
                        transaction-manager:给事务通知提供一个事务管理器引用

事务属性的一些配置信息


             3、配置AOP中的通用切入点表达式

        这个也就是说把这个事务引入到哪一个包里面的方法中,aop就相当于把一个事务类插进去,然后利用动态代理进行增强
        4、建立事务通知和切入点表达式的对应关系
        5、配置事务的属性
               是在事务的通知tx:advice标签的内部

 下面上一下全部的bean.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 配置业务层-->
    <bean id="accountService" class="com.pxx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!-- 配置账户的持久层-->
    <bean id="accountDao" class="com.pxx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>


    <!-- 配置数据源-->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
        <property name="username" value="root"></property>
        <property name="password" value="5201314"></property>
    </bean>

    <!--
    配置事务管理器
    -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--
        这个里面就需要配置一个数据源
        -->
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!--配置aop-->
    <aop:config>
        <!--配置切入点表达式-->
        <aop:pointcut id="pt1" expression="execution(* com.pxx.service.impl.*.*(..))"/>
        <!--建立切入点与事务通知的对应关系-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"></aop:advisor>
    </aop:config>

</beans>

 下面我们来测试一下正常业务转账

出现异常能不能被事务控制

 

 异常有了

数据也没有转成功

Spring基于注解的声明式事务控制

 1.一般要配置注解,就要进入context的xml约束

我们直接在原xml上修改

 

现在就可以注解了,先来配置service

 下面就可以不要了

 

 

所以上面这个AccountDaoImpl不能去继承JdbcDaoSupport

 

 

 想要配置成功,还要配置创建容器时需要扫描的包

下面就要开始配置事务了,下面说一下Spring基于注解的声明式事务控制步骤

 

 第一步:

 第二步:

引入事务管理器 

 

 第三步:

 这个属性配置好像确实不如注解方便

这个时候去测试一下

异常报了,去看一下数据

控制住了。

 Spring基于纯注解的声明式事务控制

上面还是用到部分xml配置

因为没有xml配置文件,所以我们要写一个配置类来代替xml文件

 然后上一个数据库连接的配置文件

下面看一下JdbcConifg.java

package config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import javax.sql.DataSource;

/**
 * 和连接数据库相关的配置类
 */
public class JdbcConfig {

    @Value("${jdbc.driver}")
    private String driver;

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    /**
     * 创建JdbcTemplate
     * @param dataSource
     * @return
     */
    @Bean(name="jdbcTemplate")
    public JdbcTemplate createJdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

    /**
     * 创建数据源对象
     * @return
     */
    @Bean(name="dataSource")
    public DataSource createDataSource(){
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }
}

在注解上大部分相关配置就配好了 

下面我们就要去配置事务注解的支持

 

下面去配置一下事务管理器

下面又要去创建一个配置类

然后重新改一下配置文件

 

 

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

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

相关文章

人大金仓数据库备份应用sys_dump的使用

人大金仓数据库软件给数据库管理员用户提供了管理维护数据库的多个客户端应用&#xff0c;更多参考&#xff1a;《KingbaseES客户端应用参考手册》。 我们可以看到备份的应用有两个&#xff1a; 1、sys_dump:将KingbaseES数据库备份为一个脚本文件或者其他归档文件 2、sys_d…

表单校验重要性和多规则校验

表单校验分类 校验位置&#xff1a; 客户端校验 服务端校验 表单校验框架 JSR&#xff1a;java规范提案 303&#xff1a;提供bean属性相关校验规则 JCP:java社区 Hibernate框架中包含一套独立的校验框架hibernate-validator 实际的校验规则 同一个字段有多个约束条件 引用…

股权转让项目:沈阳派尔化学有限公司55%股权转让

股权转让项目&#xff1a;沈阳派尔化学有限公司55%股权转让&#xff1b;该项目由 广州产权交易所 发布&#xff0c;于2022年12月25日被塔米狗平台收录。 该公司在 2021 年最新一期财务报告中&#xff0c; 披露的资产总额&#xff08;万元&#xff09;&#xff1a;7148.98 &…

装修半包包括哪些内容呢?极家精工装修好不好

​装修半包包括哪些内容呢&#xff1f;极家精工装修好不好。在装修房子的时候&#xff0c;很多人都会选择半包装修&#xff0c;因为可以自己挑选材料&#xff0c;自己跟工程比较放心。另外一边比较重要的原因就是能省钱&#xff0c;对于预算有限的小伙伴真的再适合不过啦&#…

唐玄奘把 「JWT 令牌」玩到了极致

唐玄奘把 「JWT 令牌」玩到了极致 你好&#xff0c;我是悟空。 西游记的故事想必大家在暑假看过很多遍了&#xff0c;为了取得真经&#xff0c;唐玄奘历经苦难&#xff0c;终于达成。 在途经各国的时候&#xff0c;唐玄奘都会拿出一个通关文牒交给当地的国王进行盖章&#x…

基于线性表的图书管理系统(java)

目录 1、简介 2、代码 &#xff08;1&#xff09;ManageSystem类 &#xff08;2&#xff09;book类 3、测试程序运行结果截图 &#xff08;1&#xff09;登录和创建 &#xff08;2&#xff09;输出 &#xff08;3&#xff09;查找 &#xff08;4&#xff09;插入 &a…

如何用乐高积木式操作让 ChatGPT 变得更强大?

需求这些日子&#xff0c;很多小伙伴儿玩儿 ChatGPT 不亦乐乎&#xff0c;甚至陷入了沉迷。他们尝试了各种 ChatGPT 的功能。不少功能强悍到不可思议&#xff1b;当然&#xff0c;也有些功能尝试因遇到障碍无法完成。于是很多用户非常失望&#xff0c;觉得 ChatGPT 好像啥都干不…

20221227:Rockchip-RK模型转换

Tips: 不同芯片对应的NPU和toolkit是不同的,注意区分! 平台 RK1808/RK1806 RV1109/RV1126 RKNPU:本工程主要为Rockchip NPU提供驱动、示例等。 GitHub - rockchip-linux/rknpuContribute to rockchip-linux/rknpu development by creating an account on GitHub.https://gi…

小程序项目开发

目录 一&#xff0c;flex弹性布局 1.什么是flex布局&#xff1f; 2.flex属性 3.视图层 View WXML 1数据绑定 2.列表渲染 3.条件渲染 4.模板 5. 数据处理 二&#xff0c;轮播图--组件的使用 1.WXSS 样式导入 内联样式 选择器 全局样式与局部样式 WXS 页面渲染 三&…

zabbix常用监控项解读

CPU来源模板&#xff1a;Template Module Linux CPU by Zabbix agent 内存&#xff08;memory&#xff09;来源模板&#xff1a;Template Module Linux memory by Zabbix agent 磁盘空间&#xff08;disk&#xff09; 数据来源&#xff1a;Get /proc/diskstats 监控项原型&am…

【小5聊】ElementUI-Vue3-TS项目简单创建

vue2升级到vue3&#xff0c;不管任何框架&#xff0c;升级总有它改进的地方和原因&#xff0c;否则升级就毫无意义&#xff0c;技术变化日新月异&#xff0c;必须保持与时俱进&#xff0c;否则就很容易在技术的浪潮中被淘汰&#xff01; vue3相比以前版本&#xff0c;最大一个变…

PyTorch笔记 - Normalization Layer (Batch\Layer\Instance\Group\Weight)

欢迎关注我的CSDN:https://blog.csdn.net/caroline_wendy 本文地址:https://blog.csdn.net/caroline_wendy/article/details/128416962 Normalization in NN: Batch Normalization: per channel across mini-batchtorch.nn.BatchNorm1d / torch.nn.BatchNorm2dLayer Normaliz…

Hive+Spark离线数仓工业项目--数仓维度层DWS层构建(1)

维度建模回顾&#xff1a;建模流程 目标&#xff1a;掌握维度建模的建模流程 实施 step1-需求调研&#xff1a;业务调研和数据调研 - 了解整个业务实现的过程 - 收集所有数据使用人员对于数据的需求 - 整理所有数据来源 step2-划分主题域&#xff1a;面向业务将业务…

盘点五款免费在线进销存系统

本文将介绍&#xff1a;1、五款好用的免费在线进销存系统&#xff1b;2、如何选择进销存软件 免费进销存是企业尝试使用进销存软件的开端&#xff0c;只有尝试之后&#xff0c;才能知道这款软件是否适合本企业的发展。然而&#xff0c;免费购买、销售和库存管理软件并不能用几个…

华为开源自研AI框架昇思MindSpore数据处理:性能优化

目录一、环境准备1.进入ModelArts官网2.使用CodeLab体验Notebook实例二、下载数据集三、数据加载性能优化四、shuffle性能优化五、数据增强性能优化六、操作系统性能优化七、自动数据加速八、数据异构加速数据是整个深度学习中最重要的一环&#xff0c;因为数据的好坏决定了最终…

基于C语言学生信息教务管理系统编程设计含科目、总分、平均分

一.实现功能 1.从键盘添加学生信息 2.从文件添加学生信息 3.显示学生信息到屏幕 4.显示学生信息到文件 5.删除学生信息 6.插入学生信息 7.查找学生信息 8.成绩排名 选1录信息 输入五个人信息 选3 选7查找信息 选2&#xff0c;导入文件 导完显示信息&#xff0c;但是中文有…

国产软件不背黑锅,4款强大又实用的电脑软件,用了舍不得卸载

国产软件常背黑锅“流氓、付费、广告多”&#xff0c;然而有些小众软件却非常良心强大&#xff0c;实在不该被牵连。 1、电脑图像工具箱 这是一个极其好用的图片处理百宝工具箱&#xff0c;完全免费无广告&#xff0c;集成工具超百个&#xff0c;功能包括&#xff1a;图像处理、…

洛谷千题详解 | P1027 [NOIP2001 提高组] Car 的旅行路线【C++语言】

博主主页&#xff1a;Yu仙笙 专栏地址&#xff1a;洛谷千题详解 目录 题目描述 输入格式 输出格式 输入输出样例 解析&#xff1a; 0.0.题意: 1.1.建图 2.2.最短路 C源码&#xff1a; C源码2&#xff1a; C源码3&#xff1a; ------------------------------------------------…

离散数学实践二编程判断关系R的性质【java实现】

文章目录实验要求思路完整代码结果展示实验要求 判断关系 R 是否为自反关系 实验类型&#xff1a;设计性实验目的 通过算法设计并编程实现对给定集合上的关系是否为自反关系的判断&#xff0c;加深学生对关系性质的理解&#xff0c;掌握用矩阵来判断关系性质的方法。 实验内容…

【Python】沃罗诺伊图 | KNN 最邻近算法 | Voronoi 函数

猛戳&#xff01;跟哥们一起玩蛇啊 &#x1f449; 《一起玩蛇》&#x1f40d; 写在前面&#xff1a;上一章我们介绍了介计算几何领域的德劳内三角剖分&#xff0c;我们提到过关于点集的很多种几何图都与德劳内三角剖分密切相关&#xff0c;其中最具代表的就是我们本章要介绍的 …