实现动态代理的两种方式

代理:比如A类需要实现查询功能,就只做查询,而开启事务交由B类处理(相当于某些事情交于其他人帮你做)。

代理类:目标被添加增强代码后,生成的新类就是代理类。

被代理类:目标类,需要被添加增强代码的类。

AOP的实现主要依赖于动态代理。

实现动态代理的两种方式:

1.JavaSE的动态代理(通过JDK):

要求:

(1)被增强对象必须实现接口;

(2)代理类必须实现java.lang.reflect.InvocationHandler接口;

(3)通过Proxy类的newProxyInstance()方法创建代理实例。

步骤:

(1)需要创建业务类和增强类的实例

ServiceInfo sInf = new ServiceImp();//创建被代理的类对象
Manager manager = new Manager();//创建增强代码类对象
(2)构建代理容器,在构造函数中传入业务对象和增强对象

InvocationHandler handler = new ProxyClass(sInf, manager);//创建代理类对象
(3)调用java.lang.reflect.Proxy类的静态函数newProxyInstance()创建动态代理对象,传入类加载器、业务接口、代理容器对象。

ServiceInfo service = (ServiceInfo)Proxy.newProxyInstance(sInf.getClass().getClassLoader(), sInf.getClass().getInterfaces(), handler);
(4)通过动态代理对象调用函数
service.add("zhangsan", 18);
service.reRs(20);
对应的业务接口,业务类,增强类,代理类,测试类如下:

ServiceInfo.java:业务接口

package service;

public interface ServiceInfo {

	void add(String name,int age);
	void reRs(int id);
}
ServiceImp.java:业务接口实现类

package service;

public class ServiceImp implements ServiceInfo{

	@Override
	public void add(String name, int age) {
		System.out.println("执行添加操作:"+name+" "+age);
		
	}

	@Override
	public void reRs(int id) {
		System.out.println("执行返回结果:"+id);
		
	}

}
Manager:增强类

package service;
/**
 * 增强类
 * @author ${HLoach}
 * 2017年3月15日
 */
public class Manager {

	public void beginTran(){
		System.out.println("【事务管理】开始事务");
	}
	
	public void commit(){
		System.out.println("【事务管理】提交事务");
	}
	
	public void rollback(){
		System.out.println("【事务管理】事务回滚");
	}
}
ProxyClass.java:代理类

package service;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyClass implements InvocationHandler{

	private Object object;//需要被代理的类
	private Manager manager;//用于执行增强操作的类
	public ProxyClass(Object object,Manager manager) {
		this.object = object;
		this.manager = manager;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//针对方法进行限制,提高AOP的灵活性
		//限制只有名称以add开头的方法才能被增强
		if(!method.getName().startsWith("add")){
			return method.invoke(object, args);//直接调用函数
		}
		manager.beginTran();
		try {
			Object rs = method.invoke(object, args);
			manager.commit();
			return rs;
		} catch (Exception e) {
			manager.rollback();
		}
		return null;
	}

}
Test1.java:测试类

package service;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class Test1 {

	public static void main(String[] args) {
		ServiceInfo sInf = new ServiceImp();//创建被代理的类对象
		Manager manager = new Manager();//创建增强代码类对象
		InvocationHandler handler = new ProxyClass(sInf, manager);//创建代理类对象
		ServiceInfo service = (ServiceInfo)Proxy.newProxyInstance(sInf.getClass().getClassLoader(), sInf.getClass().getInterfaces(), handler);//创建动态代理对象
		service.add("zhangsan", 18);
		service.reRs(20);
	}
}
执行结果如下:

【事务管理】开始事务
执行添加操作:zhangsan 18
【事务管理】提交事务
执行返回结果:20

2.通过cglib(code generation library,代码生成类库)实现动态代理,这时,被代理类(被增强对象)不用实现接口。

要求:

(1)代理类必须实现org.springframework.cglib.proxy.MethodInterceptor接口

步骤:

(1)创建增强对象

Manager manager = new Manager();
(2)创建cglib代理MethodInterceptor的实现类对象(代理类对象)

MethodInterceptor interceptor = new ProxyClass(manager);
(3)创建增强器,通过增强器设置需要被增强的类,并设置增强类回调到代理类中去使用,然后创建代理对象。

//创建增强器
Enhancer enhancer = new Enhancer();
//设置需要被增强的类
enhancer.setSuperclass(ServiceClass.class);
//设置被增强类回调到代理类中去使用
enhancer.setCallback(interceptor);
//创建代理对象
ServiceClass sClass = (ServiceClass) enhancer.create();
(4)通过代理对象调用函数

sClass.add("lisi", 23);
sClass.reRs(15);
对应增强类,代理类,测试类如下:

Manager.java:增强类

package service2;
/**
 * 增强类
 * @author ${HLoach}
 * 2017年3月15日
 */
public class Manager {

	public void beginTran(){
		System.out.println("【事务管理】开始事务");
	}
	
	public void commit(){
		System.out.println("【事务管理】提交事务");
	}
	
	public void rollback(){
		System.out.println("【事务管理】事务回滚");
	}
}
ProxyClass.java:代理类

package service2;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class ProxyClass implements MethodInterceptor{

	private Manager manager;//用于执行增强操作的类
	public ProxyClass(Manager manager) {
		this.manager = manager;
	}
	@Override
	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		if(!method.getName().startsWith("add")){
			return methodProxy.invokeSuper(object, args);//直接调用函数
		}
		manager.beginTran();
		try {
			Object rs = methodProxy.invokeSuper(object, args);//这里的object对象是被代理类对象,
                                                                       //methodProxy对象存了被代理类中所有方法
manager.commit();return rs;} catch (Exception e) {e.printStackTrace();manager.rollback();}return null;}}


ServiceClass.java:被代理类

package service2;

public class ServiceClass{

	public void add(String name, int age) {
		System.out.println("执行添加操作:"+name+" "+age);
		
	}

	public void reRs(int id) {
		
		System.out.println("执行返回结果:"+id);

	}

}

Test2.java:测试类

package service2;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

public class Test2 {

	public static void main(String[] args) {
		//创建增强对象
		Manager manager = new Manager();
		//cglib代理MethodInterceptor对象
		MethodInterceptor interceptor = new ProxyClass(manager);
		//创建增强器
		Enhancer enhancer = new Enhancer();
		//设置需要被增强的类
		enhancer.setSuperclass(ServiceClass.class);
		//设置被增强类回调到代理类中去使用
		enhancer.setCallback(interceptor);
		//创建代理对象
		ServiceClass sClass = (ServiceClass) enhancer.create();
		//通过代理对象调用函数
		sClass.add("lisi", 23);
		sClass.reRs(15);
	}
}
执行结果:

【事务管理】开始事务
执行添加操作:lisi 23
【事务管理】提交事务
执行返回结果:15














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值