Java代理模式

1.代理模式

      代理模式(Proxy),为目标对象提供一种代理以控制对目标对象的访问,即通过代理对象访问目标对象,且可以在目标对象实现的基础上增强或者删除额外的功能操作。

2.JDK静态代理

      JDK静态代理:目标对象与代理对象必须实现相同的接口或者继承相同的抽象类。eg:创建汽车类Car且汽车类Car拥有行驶的方法,针对某一个目标对象Car,生成对应的代理对象LogProxy,让代理对象拥有记录日志的功效。

1.定义接口Moveable:

package com.luna.proxy.jdk;
public interface Moveable {
	void move();
}

2.创建汽车类Car:

package com.luna.proxy.staic;
import com.luna.proxy.jdk.Moveable;
public class Car implements Moveable{
	@Override
	public void move() {
		System.out.println("小汽车行驶,嘟嘟。。。");
	}
}

3.创建汽车日志代理类LogProxy:

package com.luna.proxy.staic;
import com.luna.proxy.jdk.Moveable;
/**
 * 日志代理类
 * @author user
 */
public class LogProxy implements Moveable{
	private Moveable moveable; //聚合的方式注入对象,继承方式会导致类爆炸
	public LogProxy(Moveable moveable) {
		super();
		this.moveable = moveable;
	}
	public void move(){
		System.out.println("记录日志开始。。。");
		moveable.move();
		System.out.println("记录日志结束。。。");
	}
}

4.创建汽车日志代理类TimeProxy:

package com.luna.proxy.staic;
import com.luna.proxy.jdk.Moveable;
/**
 * 时间代理
 * @author user
 */
public class TimeProxy implements Moveable{
	private Moveable moveable; //聚合的方式注入对象,继承方式会导致类爆炸
	public TimeProxy(Moveable moveable) {
		super();
		this.moveable = moveable;
	}
	@Override
	public void move() {
		System.out.println("开始打印汽车行驶时间。。。");
		moveable.move();
		System.out.println("结束打印汽车行驶时间。。。");
	}
}

5.创建测试类:

package com.luna.proxy.staic;
import com.luna.proxy.jdk.Moveable;
/**
 * JDK静态代理测试类
 * @author user
 */
public class Test {
	public static void main(String[] args) {
		Car car = new Car();
		Moveable carProxy = new LogProxy(car);
		Moveable timeProxy = new TimeProxy(carProxy);
		timeProxy.move();
	}
}

3.JDK动态代理

JDK动态代理:针对实现某一接口的目标类,动态的生成指定功能的代理类。

1.定义接口Moveable:

package com.luna.proxy.jdk;
public interface Moveable {
	void move();
}

2.创建汽车类Car:

package com.luna.proxy.jdk;
import com.luna.proxy.jdk.Moveable;
public class Car implements Moveable{
	@Override
	public void move() {
		System.out.println("小汽车行驶,嘟嘟。。。");
	}
}

3.创建针对目标对象的事务处理器:

package com.luna.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * JDK动态代理事务处理器
 * @author user
 */
public class CarInvocationHandler implements InvocationHandler {
	private Object object;
	public CarInvocationHandler(Object object) {
		super();
		this.object = object;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("汽车开始行驶。。。");
		method.invoke(object);
		System.out.println("汽车结束行驶。。。");
		return null;
	}
}

4.创建测试类:

package com.luna.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * JDK动态代理测试类
 * @author user
 */
public class Test {
	public static void main(String[] args) {
		Car car = new Car();
		InvocationHandler h = new CarInvocationHandler(car);
		Moveable moveable = (Moveable)Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), h);
		moveable.move();
	}
}

4.CGLIB动态代理

      CGLIB动态代理:针对某一目标对象,生成对应目标对象的代理子类(不用实现接口)必须引入CGLIB依赖包cglib-3.2.5.jar,代理类会拦截目标对象的所有非final/static修饰的方法,如果目标类被final关键字修饰,则不能使用CGLIB动态代理。

1.创建汽车类Car:

package com.luna.proxy.cglib;
public class Car {
	public void move(){
		System.out.println("小汽车行驶,嘟嘟。。。");
	}
}

3.创建CGLIB代理类:

package com.luna.proxy.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/**
 * CGLIB代理拦截器
 * @author user
 */
public class CarProxy implements MethodInterceptor {
	private Enhancer enhancer = new Enhancer();
	public Object getProxy(Class<?> clazz){
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);
		return enhancer.create();
	}
	@Override
	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
		System.out.println("日志记录开始。。。");
		proxy.invokeSuper(obj, args);
		System.out.println("日志记录结束。。。");
		return null;
	}
}

4.创建测试类:

package com.luna.proxy.cglib;
/**
 * CGLIB动态代理测试类
 * @author user
 */
public class Test {
	public static void main(String[] args) {
		CarProxy carProxy = new CarProxy();
		Car car = (Car)carProxy.getProxy(Car.class);
		car.move();
	}
}

4.总结

      在Spring的AOP编程中:如果加入容器的目标对象有实现接口则用JDK动态代理;如果目标对象没有实现接口则使用Cglib动态代理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

抽离的心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值