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动态代理。