静态代理
Maven创建工程
- 被代理类:业务核心
- 代理类: 非业务核心(事务、性能)
- 代理类实现被代理类的所有接口
- 代理类中需要有被代理类的实例对象(原有业务需要被代理类来执行)
- 在代理类的方法中,对原有业务进行增强(性能、事务)
package Dao;
public interface AccountDao {
void update(String from, int i);
}
接口实现类:
package Dao.Impl;
import Dao.AccountDao;
import org.apache.commons.dbutils.QueryRunner;
import utils.JdbcUtil;
import java.sql.SQLException;
public class AccountDaoImpl implements AccountDao {
public void update(String account, int money) {
QueryRunner queryRunner = new QueryRunner();
String sql = "update account set money = money+? where account = ?";
try {
queryRunner.update( JdbcUtil.getConnection(),sql,money,account);
System.out.println("成功");
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
数据据库连接
util:
package utils;
import java.sql.*;
import java.util.ResourceBundle;
public class JdbcUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
private static final ThreadLocal<Connection> t = new ThreadLocal<Connection>(); //保证在同一个线程中,对象唯一
static{
try {
//读取配置文件中的信息
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
driver =rb.getString("jdbc.driver");
url = rb.getString("jdbc.url");
username = rb.getString("jdbc.username");
password = rb.getString("jdbc.password");
//加载驱动
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//建立连接
public static Connection getConnection(){
Connection con = null;
con = t.get();
if(con == null) {
try {
con = DriverManager.getConnection(url, username, password);
t.set(con);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
return con;
}
//关闭资源
public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
if(resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/shopping?&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=1234
业务层(service)
public interface Accountservice {
void transfer(String from,String to,int money);
}
实现类
package service.Impl;
import Dao.AccountDao;
import Dao.Impl.AccountDaoImpl;
import service.Accountservice;
//被代理类
public class AccountserviceImpl implements Accountservice {
public void transfer(String from, String to, int money) {
AccountDao accountDao = new AccountDaoImpl();
accountDao.update(from, -money);
// System.out.println(1/0);// 异常
accountDao.update(to, money);
}
}
package service.Impl;
import service.Accountservice;
import utils.JdbcUtil;
import java.sql.Connection;
import java.sql.SQLException;
//代理类
public class AccountServletProxy implements Accountservice { //实现被代理类的接口
private AccountserviceImpl accountservice; //创建被代理类的实例
public AccountServletProxy() {
}
public AccountServletProxy(AccountserviceImpl accountservice) { //需要给被代理类实例赋值创建的对象,提供的有参构造
this.accountservice = accountservice;
}
public void transfer(String from, String to, int money) { //重写被代理类的所有接口方法
Connection connection = null;
try {
connection = JdbcUtil.getConnection();
connection.setAutoCommit(false); //开启事务
// accountDao.update(from, -money);
// // System.out.println(1/0); 异常
// accountDao.update(to, money);
accountservice.transfer(from, to, money); //业务核心
} catch (Exception e) {
e.printStackTrace();
try {
connection.rollback(); //事务回滚
} catch (SQLException throwables) {
throwables.printStackTrace();
}
} finally {
try {
connection.commit(); //提交事务
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
Mysql数据库
accoun表:
CREATE TABLE `account` (
`id` int NOT NULL AUTO_INCREMENT,
`account` varchar(20) DEFAULT NULL,
`money` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
测试类
Test:
import org.junit.Test;
import service.Impl.AccountServletProxy;
import service.Impl.AccountserviceImpl;
public class Tester {
@Test
public void test(){
AccountserviceImpl accountservice = new AccountserviceImpl();
AccountServletProxy accountServletProxy = new AccountServletProxy(accountservice);
accountServletProxy.transfer("tom","jack",100);
// accountservice.transfer("tom","jack",100);
}
}
pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>account</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
静态代理的缺点:
需要为内一个内创建代理类,有多少需要增强的类就得创建多少个代理类;代理类中增加了业务方法,被代理类中也要相应的方法,增强的代码一样,代码重复。