我们需要通过以下这一句获得代理对象,它有固定的格式
return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader() ,accountService.getClass().getInterfaces(),
new InvocationHandler() {…}
1)返回一个代理对象的方式 (IAccountService)强转成所代理的对象
2)CGlib所提供的代理对象的生成方法方法:Proxy.newProxyInstance
3)获得所代理对象的Class类文件:accountService.getClass().getClassLoader() ,
4)获得所代理对象的所有方法:accountService.getClass().getInterfaces(),
5)必须实现的new InvocationHandler() {…}方法
所代理对象的所有方法的执行rtValue = method.invoke(accountService, args)的前后都会走这些事务。
package com.itheima.factory;
import com.itheima.service.IAccountService;
import com.itheima.utils.TransactionManager;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 用于创建Service的代理对象的工厂
*/
public class BeanFactory {
private IAccountService accountService;
private TransactionManager txManager;
public void setTxManager(TransactionManager txManager) {
this.txManager = txManager;
}
public final void setAccountService(IAccountService accountService) {//这里必须是final
this.accountService = accountService;
}
/**
* 获取Service代理对象
* @return
*/
public IAccountService getAccountService() {
return (IAccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(),
accountService.getClass().getInterfaces(),
new InvocationHandler() {
/**
* 添加事务的支持
*
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("test".equals(method.getName())){
return method.invoke(accountService,args);
}
Object rtValue = null;
try {
//1.开启事务
txManager.beginTransaction();
//2.执行操作
rtValue = method.invoke(accountService, args);
//3.提交事务
txManager.commit();
//4.返回结果
return rtValue;
} catch (Exception e) {
//5.回滚操作
txManager.rollback();
throw new RuntimeException(e);
} finally {
//6.释放连接
txManager.release();
}
}
});
}
}