定义
通过代理对象访问目标对象
特点
代理对象可以在目标对象实现的基础上,扩展目标对象的功能
静态代理
代理对象和目标对象一起实现相同的接口或者是继承相同的父类
public class Car implements Moveable {
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
/* Car car= new Car();
CarTimeProxy carTimeProxy = new CarTimeProxy(moveable);
CarLogProxy carLogProxy = new CarLogProxy(carTimeProxy);
carLogProxy.move();*/
new CarLogProxy(
new CarTimeProxy(
new Car()
)
).move();
}
}
//增加了记录Car运动时间的功能
class CarTimeProxy implements Moveable{
//目标对象是Car,代理对象是CarTimeProxy
//接收保存目标对象
Moveable moveable;
public CarTimeProxy(Moveable moveable){
this.moveable = moveable;
}
@Override
public void move() {
System.out.println("Car moving 轰轰轰!");
long start = System.currentTimeMillis();
moveable.move();
long end = System.currentTimeMillis();
System.out.println("汽车运行了"+(end-start)/1000+"秒"+"真的好厉害啊!");
}
}
//增加了记录Car开始和结束的日志动作
class CarLogProxy implements Moveable{
//目标对象是CarTimeProxy,代理对象是CarLogProxy
//接收保存目标对象
Moveable moveable;
public CarLogProxy(Moveable moveable){
this.moveable = moveable;
}
@Override
public void move() {
System.out.println("Car开始运动了!");
moveable.move();
System.out.println("Car结束运动了!");
}
}
interface Moveable {
void move();//移动的动作
}
动态代理
- jdk动态代理
利用反射机制生成一个实现代理接口的匿名对象类,在调用具体方法前调用InvocationHandler类来处理 - cglib动态代理
利用ASM(开源的Java字节码编辑库,操作字节码)开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理
JDK动态代理
public class Car implements Movable{
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Car car = new Car();
Movable movable = (Movable) Proxy.newProxyInstance(
Car.class.getClassLoader(),//目标对象,需要用哪个loader把new出来的代理对象给load到内存中,一般写被代理对象的
new Class[]{Movable.class},//接口,代理对象应该实现哪些接口
new InvocationHandler() { //被代理对象方法被调用的时候我们如何做处理
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* proxy:生成的代理对象
* method:正在调用的方法
* args:往方法里面传入的参数
*/
System.out.println("method:"+method.getName()+":start...");
/**
* 传入哪个应用就相当于调用哪个引用的方法
* 方法被调用的时候需要告诉方法由谁来调用它
*/
Object o = method.invoke(car, args);
System.out.println("method:"+method.getName()+":end...");
return o;
}
}
);
/**
* 动态生成的代理类会生成代理方法,
* 代理类会调用自己的move方法,move方法调用invoke方法,invoke方法调用car的move方法
*/
movable.move();
}
}
interface Movable{
void move();
}
生成动态代理对象的关键代码
loader:用哪个类加载器去加载代理对象
interfaces:动态代理类需要实现的接口
h:动态方法在执行时,会调用h里面的invoke方法去执行
Proxy.newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
优化版本一
public class Car implements Movable{
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(10000));//随机slepp[0-9),模拟汽车运动的时间
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Car car = new Car();
Movable movable = (Movable) Proxy.newProxyInstance(
Car.class.getClassLoader(),
new Class[]{Movable.class},
new LogHander(car)
);
movable.move();
}
}
class LogHander implements InvocationHandler{
Car car;
public LogHander(Car car){
this.car = car;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method:"+method.getName()+":start...");
Object o = method.invoke(car, args);
System.out.println("method:"+method.getName()+":end...");
return o;
}
}
interface Movable{
void move();
}
优化版本二
public class Car implements Moveable{
@Override
public void move() {
try {
Thread.sleep(new Random().nextInt(10000));
}catch (Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Car car = new Car();
Moveable moveable = (Moveable) Proxy.newProxyInstance(
Car.class.getClassLoader(),
new Class[]{Moveable.class},
new LogHandler(car)
);
moveable.move();
}
}
class LogHandler implements InvocationHandler{
Car car = new Car();
public LogHandler(Car car){
this.car=car;
}
public void before() {
System.out.println("method:"+"start...");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object o = method.invoke(car, args);
after();
return o;
}
public void after() {
System.out.println("method:"+"stop...");
}
}
interface Moveable{
void move();//移动
}
cglib的动态代理
/**
* cglib的动态代理
*/
public class Main {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();//增强器
enhancer.setSuperclass(Car.class);//设置Car为父类
enhancer.setCallback(new TimeMethodInterceptor());//设置回调函数
Car car = (Car) enhancer.create();//调用create方法
car.move();
}
}
class TimeMethodInterceptor implements MethodInterceptor{
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//System.out.println(o.getClass().getSuperclass());输出Object o的父类对象,o为Car的子类,若Car使用fina修饰,无法使用cglib代理
System.out.println("Car start moving");
Object result = null;
result = methodProxy.invokeSuper(o, objects);
System.out.println("Car stop moving");
return result;
}
}
class Car {
public void move(){
try {
System.out.println("Car is moving");
Thread.sleep(new Random().nextInt(1000));
}catch (Exception e){
e.printStackTrace();
}
}
}