/* 动态代理处理service
* 1、动态代理的核心是切面编程,去除重复代码;
* 2、通过反射+注解可以灵活的获取传入对象内容;
* 3、通过try+catch将多个操作包裹,实现事物的原子性;
*
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
// 声明空对象
Object result = null;
// 通过方法获取真实实现类的调用方法
Method m = obj.getClass().getMethod(method.getName(), method.getParameterTypes());
// 获取调用方法的注解
Transactional annotation = m.getDeclaredAnnotation(Transactional.class);
// 判断注解为空则表示操作不是事物,无需满足原子性
if (annotation == null) {
System.out.println("非事务对象");
// 获取数据库接口
conn = SQLuntil.getConnection();
// 通过反射获取真实实现类的全部成员变量并遍历每个成员变量(即dao层接口实现类)
for (Field field : obj.getClass().getDeclaredFields()) {
// 允许访问私有成员变量
field.setAccessible(true);
// 获取dao层接口实现类对象
Object daoobj = field.get(obj);
// 通过反射获取dao层接口实现类对象的Connection对象
Field fconn = daoobj.getClass().getDeclaredField("conn");
// 允许访问私有成员变量
fconn.setAccessible(true);
// 为Connection对象赋值
fconn.set(daoobj, conn);
}
// 通过反射调取真实实现类方法并返回对应结果
result = method.invoke(obj, args);
// 关闭数据库接口
SQLuntil.close(conn);
}
// 判断存在注解表示操作对象是事物,需满足原子性更改为手动提交,如果过程中出现错误需要回滚
else {
try {
System.out.println("事务对象");
// 获取数据库接口
conn = SQLuntil.getConnection();
// 取消自动数据提交
conn.setAutoCommit(false);
// 通过反射获取真实实现类的全部成员变量并遍历每个成员变量(即dao层接口实现类)
for (Field field : obj.getClass().getDeclaredFields()) {
// 允许访问私有成员变量
field.setAccessible(true);
// 获取dao层接口实现类对象
Object daoobj = field.get(obj);
// 通过反射获取dao层接口实现类对象的Connection对象
Field fconn = daoobj.getClass().getDeclaredField("conn");
// 允许访问私有成员变量
fconn.setAccessible(true);
// 为Connection对象赋值
fconn.set(daoobj, conn);
}
// 通过反射调取真实实现类方法并返回对应结果
result = method.invoke(obj, args);
// 提交数据到数据库
conn.commit();
} catch (Exception e) {
// TODO: handle exception
// 捕获异常数据进行回滚
conn.rollback();
e.printStackTrace();
} finally {
// 关闭数据库接口
SQLuntil.close(conn);
}
}
return result;
}