欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > SpringAOP的引入

SpringAOP的引入

2024/11/30 9:38:28 来源:https://blog.csdn.net/2201_76081438/article/details/143396741  浏览:    关键词:SpringAOP的引入

目录

一、概念引入

1.引入依赖

2.工具类

3.实体类

4.持久层实现类

5.业务层实现类

6.配置文件

7.测试类

8.运行

查看数据库:

9.现在如果转账过程中出现异常

AccountServiceImpl(模拟异常)

再运行:

查看数据库: 

10.现在做事务管理

AccountServiceImpl(事务管理)

运行

查看数据库:

11.生成代理对象

代理对象:

业务层实现类

查看数据库:


一、概念引入

入门案例(概念引入)

1.引入依赖

<dependencies><!--spring的核心依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><!-- https://mvnrepository.com/artifact/log4j/log4j --><!--日志--><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><!--测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--连接池 alibaba的--><!-- https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--mysql驱动--><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version></dependency><!--spring-test--><!-- https://mvnrepository.com/artifact/org.springframework/spring-test --><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>5.0.2.RELEASE</version><scope>test</scope></dependency>
</dependencies>

2.工具类

package com.qcby.utils;import java.sql.Connection;
import java.sql.SQLException;import javax.sql.DataSource;import com.alibaba.druid.pool.DruidDataSource;/*** 事务的工具类*/
public class TxUtils {private static DruidDataSource ds = null;// 使用ThreadLocal存储当前线程中的Connection对象private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();// 在静态代码块中创建数据库连接池---static代码块static {try {// 通过代码创建C3P0数据库连接池ds = new DruidDataSource();ds.setDriverClassName("com.mysql.jdbc.Driver");ds.setUrl("jdbc:mysql:///spring_db");ds.setUsername("root");ds.setPassword("2020");} catch (Exception e) {throw new ExceptionInInitializerError(e);}}/*** @Method: getConnection* @Description: 从数据源中获取数据库连接* @Anthor:* @return Connection* @throws SQLException*/public static Connection getConnection() throws SQLException {// 从当前线程中获取ConnectionConnection conn = threadLocal.get();if (conn == null) {// 从数据源中获取数据库连接conn = getDataSource().getConnection();// 将conn绑定到当前线程threadLocal.set(conn);}return conn;}/*** @Method: startTransaction* @Description: 开启事务* @Anthor:**///jdbc开启事务靠链接开启public static void startTransaction() {try {Connection conn = threadLocal.get();if (conn == null) {conn = getConnection();// 把 conn绑定到当前线程上threadLocal.set(conn);}// 开启事务conn.setAutoCommit(false);} catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: rollback* @Description:回滚事务* @Anthor:*/public static void rollback() {try {// 从当前线程中获取ConnectionConnection conn = threadLocal.get();if (conn != null) {// 回滚事务conn.rollback();}} catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: commit* @Description:提交事务* @Anthor:*/public static void commit() {try {// 从当前线程中获取ConnectionConnection conn = threadLocal.get();if (conn != null) {// 提交事务conn.commit();}} catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: close* @Description:关闭数据库连接(注意,并不是真的关闭,而是把连接还给数据库连接池)* @Anthor:**/public static void close() {try {// 从当前线程中获取ConnectionConnection conn = threadLocal.get();//从连接池拿到链接if (conn != null) {conn.close();// 解除当前线程上绑定connthreadLocal.remove();}} catch (Exception e) {throw new RuntimeException(e);}}/*** @Method: getDataSource* @Description: 获取数据源* @Anthor:* @return DataSource*/public static DataSource getDataSource() {// 从数据源中获取数据库连接return ds;}}

3.实体类

package com.qcby.model;import java.io.Serializable;public class Account implements Serializable {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;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}

4.持久层实现类

package com.qcby.dao.impl;import com.qcby.dao.AccountDao;
import com.qcby.pojo.Account;
import com.qcby.utils.TxUtils;import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import com.mysql.jdbc.Driver;public class AccountDaoImpl implements AccountDao {//实现两个账户的转账@Overridepublic void updateSaveAll(Account account){Connection connection=null;PreparedStatement stmt=null;try{//获取连接connection = TxUtils.getConnection();String sql = "update  account set money = money + ? where name = ?";stmt = connection.prepareStatement(sql);stmt.setDouble(1, account.getMoney());stmt.setString(2, account.getName());// 查询int result = stmt.executeUpdate();System.out.println("修改影响了"+result+"行数据!!");}catch(Exception e){try {stmt.close();//connection.close();} catch (SQLException e1) {e1.printStackTrace();}}}
}

5.业务层实现类

package com.qcby.service.impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void updateSaveAll(Account account1, Account account2) {//保存账号1accountDao.updateSaveAll(account1);//保存账号2accountDao.updateSaveAll(account2);}
}

6.配置文件

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置持久层和业务层--><bean id="accountService" class="com.qcby.service.impl.AccountServiceImpl"><property name="accountDao" ref="accountDao"></property></bean><bean id="accountDao" class="com.qcby.dao.impl.AccountDaoImpl"></bean></beans>

7.测试类

package com.qcby;import com.qcby.model.Account;
import com.qcby.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class demo {@Autowiredprivate AccountService accountService;@Testpublic void run(){Account account1=new Account(null,"aaa",500.00);Account account2=new Account(null,"bbb",-500.00);accountService.updateSaveAll(account1,account2);}
}

8.运行

查看数据库:

之前:

现在:

9.现在如果转账过程中出现异常

AccountServiceImpl(模拟异常)

package com.qcby.service.impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void updateSaveAll(Account account1, Account account2) {//保存账号1accountDao.updateSaveAll(account1);//模拟异常int a=1/0;//保存账号2accountDao.updateSaveAll(account2);}
}

再运行:

查看数据库: 

只有第一条数据变了,出现错误

10.现在做事务管理

AccountServiceImpl(事务管理)

package com.qcby.service.impl;import com.qcby.dao.AccountDao;
import com.qcby.model.Account;
import com.qcby.service.AccountService;
import com.qcby.utils.TxUtils;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}@Overridepublic void updateSaveAll(Account account1, Account account2) {//在这里进行事务管理try {//开启事务TxUtils.startTransaction();//保存账号1accountDao.updateSaveAll(account1);//模拟异常int a=1/0;//保存账号2accountDao.updateSaveAll(account2);//提交事务TxUtils.commit();}catch (Exception e){e.printStackTrace();//回滚事务TxUtils.rollback();}finally {//关闭资源TxUtils.close();}}
}

这里仍然有异常,但是进行了事务管理,

运行

查看数据库:

原来:

 现在:

 回滚了

11.生成代理对象

代理对象:

package com.qcby.proxy;import com.qcby.service.AccountService;
import com.qcby.utils.TxUtils;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;/*
* 传入目标对象,生成该对象的代理对象,返回。对目标对象的方法进行增强
* */
public class JdkProxy {//获取代理对象public static Object getProxy(AccountService accountService){/** 使用JDK动态代理生成代理对象* 第一个参数:类的加载其* 第二个参数:当前传入的对象实现了哪些接口要字节码的对象* 第三个参数:回调函数* */Object proxy = Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler(){public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result = null;try {//开启事务TxUtils.startTransaction();result = method.invoke(accountService,args);//提交事务TxUtils.commit();}catch (Exception e){e.printStackTrace();//回滚TxUtils.rollback();}finally {TxUtils.close();}return result;}});return proxy;}
}

业务层实现类

(有异常)(之前在这里写的事务就不用写了)

package com.qcby.service.impl;import com.qcby.dao.AccountDao;
import com.qcby.pojo.Account;
import com.qcby.service.AccountService;
import com.qcby.utils.TxUtils;import java.sql.SQLException;public class AccountServiceImpl implements AccountService {private AccountDao accountDao;//因为这里是空指针,所以要有set方法public void setAccountDao(AccountDao accountDao) {this.accountDao = accountDao;}public void updateSaveAll(Account account1, Account account2){try {//保存账号1accountDao.updateSaveAll(account1);//模拟异常int a=1/0;//保存账号2accountDao.updateSaveAll(account2);}catch (Exception e){e.printStackTrace();}}
}

测试类

(多了一个run2())

package com.qcby.springAopTest;import com.qcby.pojo.Account;
import com.qcby.proxy.JdkProxy;
import com.qcby.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {@Autowiredprivate AccountService accountService;@Testpublic void run1(){Account account1=new Account(null,"aaa",500.00);Account account2=new Account(null,"bbb",-500.00);accountService.updateSaveAll(account1,account2);}@Testpublic void run2(){Account account1=new Account(null,"aaa",500.00);Account account2=new Account(null,"bbb",-500.00);//生成代理对象Object proxyobj= JdkProxy.getProxy(accountService);AccountService proxy=(AccountService)proxyobj;proxy.updateSaveAll(account1,account2);}
}

运行:

查看数据库:

原来:

现在:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com