动态代理(了解但不常用)

package com.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;

/**
 * 动态代理工具类
 * 
 * @author zhaoj
 *
 */
public class ServiceProxyUtil implements InvocationHandler {

	private Object targertObj;// 目标对象的引用,用于在invoke方法中执行目标方法

	// 根据目标对象的引用,动态创建这个引用对象的代理对象
	public Object newProxyObject(Object targerObj) {
		this.targertObj = targerObj;
		// 创建动态代理对象
		// 参数1 目标对象的类加载器
		// 参数2 目标对象的所有父接口的Class
		// 参数3 某个InvocationHandler的接口对象,
		// 作用是:通知JVM这个代理对象在执行方法时要调用哪个类中的invoke方法
		return Proxy.newProxyInstance(targerObj.getClass().getClassLoader(), targerObj.getClass().getInterfaces(),
				this);
	}
	
	/*
	 * 动态代理的通用代理方法,当代理对象调用任何一个方法时都会自动执行这个invoke方法.JVM完成自动调用这个方法
	 * 
	 * 参数1 代理对象的引用,注意:这个对象最好不要使用
	 * 参数2 目标方法的反射引用对象
	 * 参数3 执行目标方法时所需要的参数列表,如果目标方法没有参数那么这个数组的长度为0
	 * 返回值Object  为目标方法的返回值数据,如果目标方法返回值类型为void 那么这个方法应该返回 null
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		Object result = null;
		
		Connection conn = DBUtil.getConn();
		
		try {
			result = method.invoke(targertObj, args);//执行目标方法
			conn.commit();//事务提交
			
		} catch (Exception e) {
			e.printStackTrace();
			conn.rollback();//事务回滚
		}finally{
			DBUtil.close(null, null, conn);
		}
		return result;
	}

}



package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 数据库工具类
 * 
 * @author zhaoj
 *
 */
public class DBUtil {

	private static ThreadLocal<Connection> local = new ThreadLocal<>();

	static {
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获得数据库连接对象
	 * 
	 * @return
	 */
	public static Connection getConn() {
		// 根据当前线程对象,从容器中获取数据库连接
		Connection conn = local.get();
		if (conn == null) {
			// 如果没有数据库连接,新创建一个
			try {
				conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mvc", "root", "root");
				// 设置数据库手动提交
				conn.setAutoCommit(false);
			} catch (SQLException e) {
				e.printStackTrace();
			}

		}
		// 如果有的话直接返回,这样保证了同一个线程中Connection是相同的
		return conn;
	}

	/**
	 * 关闭资源
	 * 
	 * @param rs
	 * @param pre
	 * @param conn
	 */
	public static void close(ResultSet rs, PreparedStatement pre, Connection conn) {
		try {
			if (rs != null) {
				rs.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		try {
			if (pre != null) {
				pre.close();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		try {
			if (conn != null) {
				conn.close();
				local.remove();// 当使用完,从容器中移出,否则容易造成内存溢出
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

如何使用:

AccountService service=(AccountService) new ServiceProxyUtil().newProxyObject(new AccountServiceImpl());
Integer result =service.transfer(fromAccount,toAccount,money);//调用代理对象的代理方法


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值