动态JDK代理方式-实现类增强

需求描述:

  抽取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?尚未知晓
Best Regards
原文地址:https://www.cnblogs.com/pecool/p/8261738.html