JAVA程式設計119——事務控制/動態代理/程式碼優化
阿新 • • 發佈:2018-11-08
一、優化方案:將代理類單獨抽取出來封裝成為一個代理工廠
package com.mollen.config;
import com.mollen.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @ClassName: BeanFactory
* @Auther: Mollen
* @CreateTime: 2018-11-07 16:00:35
* @Description:
* 方法引數service為需要增強的類物件
*
*/
public class ProxyFactory {
/**
* 1.jdk動態代理事務
* @param service
* @return
*/
public static Object transferUseJdk (final Object service) {
/**
* ClassLoader loader, 真實物件的類載入器
* Class<?>[] interfaces, 真實物件實現的所有介面
* InvocationHandler h 代理物件的處理類
*/
Object proxy = Proxy.newProxyInstance(
service.getClass().getClassLoader(),
service. getClass().getInterfaces(),
new InvocationHandler() {
/**
* 呼叫代理物件任意方法,InvocationHandler中的invoke()都會執行
* @param proxy 代理物件
* @param method 代理物件呼叫的方法
* @param args 代理物件呼叫方法時摻入的引數
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//宣告一個事務執行結果
Object obj = null;
try {
//1.開啟事務--業務執行之前
TransactionManager.startTransaction();
//2.執行業務--執行業務操作
obj = method.invoke(service, args);
//3.提交事務--業務正常執行
TransactionManager.commitTransaction();
} catch (Exception e) {
//4.回滾事務--業務執行異常
TransactionManager.rollbackTransaction();
e.printStackTrace();
} finally {
//5.關閉連線
TransactionManager.close();
}
return obj;
}
});
return proxy;
}
/**
* 2.cglib動態代理事務1
* @param service
* @return
*/
public static Object transferUseCglib(final Object service) {
//1. 建立cglib的核心物件
Enhancer enhancer = new Enhancer();
//2. 設定產生的代理物件的父類
enhancer.setSuperclass(service.getClass());
//3. 設定呼叫代理物件的回撥函式
enhancer.setCallback(new MethodInterceptor() {
/**
*
* @param proxy 代理物件
* @param method 代理物件執行的方法
* @param args 代理物件呼叫方法時傳入的引數
* @param methodProxy 呼叫方法的代理物件 一般沒什麼用
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj = null;
try {
//1. 在轉賬業務執行之前 開啟事物
TransactionManager.startTransaction();
//2. 執行原有的轉賬業務
obj = method.invoke(service, args);
//3. 轉賬業務執行成功-- 提交事物
TransactionManager.commitTransaction();
} catch (Exception e) {
e.printStackTrace();
//4. 轉賬業務執行失敗---回滾事物
TransactionManager.rollbackTransaction();
} finally {
TransactionManager.close();
}
return obj;
}
});
return enhancer.create();
}
/**
* 2.cglib動態代理事務2
* @param service
* @return
*/
public static Object transferUseCglibPlus(final Object service) {
return Enhancer.create(
service.getClass(),
new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj = null;
try {
TransactionManager.startTransaction(); //1.開啟事物
obj = method.invoke(service, args); //2. 執行業務
TransactionManager.commitTransaction(); //3. 提交事物
} catch (Exception e) {
TransactionManager.rollbackTransaction(); //4. 回滾事物
e.printStackTrace();
} finally {
TransactionManager.close(); //5. 關閉連線
}
return obj;
}
});
}
}
二、建立測試類:MyTest2.java
package com.mollen.test;
import com.mollen.config.ProxyFactory;
import com.mollen.service.AccountService;
import com.mollen.service.impl.AccountServiceImpl;
import org.junit.Test;
/**
* @ClassName: MyTest2
* @Auther: Mollen
* @CreateTime: 2018-11-07 16:28:15
* @Description:
*/
public class MyTest2 {
private AccountService accountService = new AccountServiceImpl();
private AccountService proxy;
/**
* 1.jdk動態代理事務測試
*/
@Test
public void test01() throws Exception {
proxy = (AccountService)ProxyFactory.transferUseJdk(accountService);
proxy.transfer("aaa", "bbb", 100);
}
/**
* 2.cglib動態代理事務測試1
*/
@Test
public void test02() throws Exception {
proxy = (AccountService)ProxyFactory.transferUseCglib(accountService);
proxy.transfer("aaa", "bbb", 100);
}
/**
* 3.cglib動態代理事務測試2
*/
@Test
public void test03() throws Exception {
proxy = (AccountService)ProxyFactory.transferUseCglibPlus(accountService);
proxy.transfer("aaa", "bbb", 100);
}
}