需求描述:

  抽取dao层开启和提交事物交由代理类一并执行

分析:

  假如UserDao接口中有很多方法,例如addUser()、deleteUser()、updateUser()等等,需要频繁的和数据库打交道,必然在每个方法里都会有开启事物,提交事务的操作。如果把开启事物和提交事物写在一个类A中不同方法中,由一个工厂将dao层和A类进行整合,得到一个代理的UserDao的实现对象,它即有原UserDao实现类中的各个方法,又有A类中的事物方法。即可实现切面管理事物。

代码:

UserDao接口:

package com.xx.dao;

public interface UserDao {
//增
void addUser();
//删
void deleteUser();
//改
void updateUser();
}

UserDaoImpl实现类:

package com.xx.dao;

public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
@Override
public void updateUser() {
System.out.println("更新用户");
}
}

切面类:

package com.xx.dao;

public class MyAspect {
public void before(){
System.out.println("开启事物");
}
public void after(){
System.out.println("关闭事物");
}
}

代理工厂类:

package com.xx.dao;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理工厂(代理UserDao生成特定功能的实现类对象)
* @author phoebe
*
*/
public class ProxyFactory {
//被代理类
private static UserDao userDao = new UserDaoImpl();
//切面类
private static MyAspect myAspect = new MyAspect();
/* 获取新的代理类
* loader:类加载器(选当前类的类加载器)
* 方法一:当前类.class.getClassLoader();
* 方法二:对象.getClass.getClassLoader();
* interfaces:代理生成的对象是哪个接口的实现类呢?
* 方法一:new Class[]{接口.class}
* 方法二:对象.getClass().getInterfaces(),此仅能返回当前对象实现类的接口,并不能返回其父接口
* InvocationHandler:使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的 Proxy 实例。
*/
public static UserDao createProxyUserService(){
UserDao proxyInstance = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object object = null;
//可以通过method.getName()控制是否增强
if(!("updateUser".equals(method.getName()))){
myAspect.before();
object = method.invoke(userDao, args);
myAspect.after();
System.out.println(object+"为什么是null?尚未知晓");
return object;
}
System.out.println(object+"为什么是null?尚未知晓");
return object;
}
});
//返回UserDao的新实例对象
return proxyInstance;
}
}

测试类:

package com.xx.action;
import com.xx.dao.ProxyFactory;
import com.xx.dao.UserDao;
public class TestProxy {
public static void main(String[] args) {
UserDao userService = ProxyFactory.createUserService();
userService.addUser();
userService.deleteUser();
userService.updateUser();
}
}

效果:

开启事物
-------添加用户-------
关闭事物
null为什么是null?尚未知晓
开启事物
-------删除用户-------
关闭事物
null为什么是null?尚未知晓
null为什么是null?尚未知晓

最新文章

  1. Flexible 弹性盒子模型之flex
  2. php版的redis操作库predis操作大全
  3. 每日Scrum(3)
  4. my_mosaic
  5. iOS button文字居中
  6. Unity光照
  7. [置顶] iOS开发规范
  8. SqlServer中截取字符串
  9. SpringMVC07处理器方法的返回值
  10. day3_python学习笔记_chapter5_数字
  11. jmeter测试HTTP请求
  12. 四.RabbitMQ之发布/订阅(Publish/Subscribe)
  13. Effective Java 第三版——14.考虑实现Comparable接口
  14. ssr 服务端安装教程
  15. Android开发技巧——定制仿微信图片裁剪控件
  16. CollectionUtils工具类的常用方法
  17. P5239 回忆京都
  18. Windows10安装Docker
  19. linux4.10.8 内核移植(四)---字符设备驱动_led驱动程序
  20. GuavaCache学习笔记三:底层源码阅读

热门文章

  1. spring boot +mysql + mybatis + druid的整理(一)——单数据源
  2. 【易语言学习】Day1
  3. 【Java学习笔记之八】JavaBean中布尔类型使用注意事项
  4. 【Java学习笔记之三】java中的变量和常量
  5. qsc oj 22 哗啦啦村的刁难(3)(随机数,神题)
  6. 安装linux的关键步骤
  7. [国嵌攻略][072][Linux应用程序地址布局]
  8. [国嵌笔记][031][Bootloader架构设计]
  9. AMD规范学习笔记
  10. Flume介绍