avatar

目录
实现Java动态代理

Java动态代理

JDK动态代理

类的准备

  • 定义接口类Animal
java
1
2
3
public interface Animal {
public void run();
}
  • 定义Animal的实现类Dog类
java
1
2
3
4
5
6
public class Dog implements Animal {
@Override
public void run() {
System.out.println("Dog can run!!!!");
}
}

两种方式实现jdk动态代理

方式一:使用匿名内部类的方式

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 使用匿名内部类的方式去实现动态代理过程
public class MainTest2 {
public static void main(String[] args) {
Animal proxyAnimal = (Animal)Proxy.newProxyInstance(Dog.class.getClassLoader(), Dog.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Dog dog = new Dog();
System.out.println("啊。。我被增强了");
Object result = method.invoke(dog, args);
return result;
}
});
proxyAnimal.run();
}
}

方式二:使用创建InvocationHandler子类的方式去实现动态代理

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MainTest {
public static void main(String[] args) {
// 实现类animalProxy是代理类
Dog dog = new Dog();
Animal animalProxy = (Animal)Proxy.newProxyInstance(Dog.class.getClassLoader(),Dog.class.getInterfaces(),new MyInvocationHandler(dog));
animalProxy.run();
}
}

class MyInvocationHandler implements InvocationHandler {
private Object target;
public MyInvocationHandler(Object target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("啊。。我被增强了");
Object invoke = method.invoke(target, args);
return invoke;
}
}

cglib动态代理方式

cglib既可以对接口进行代理,又可以针对实现类进行代理。

  1. 类的准备如上,都是一个Dog和Animal。

cglib代理实现的两种方式

  1. 匿名内部类方式

    java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class MyCgLibTest {
    public static void main(String[] args) {
    Dog dog = (Dog)Enhancer.create(Dog.class, new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    Object result = null;
    if ("run".equals(method.getName())){
    System.out.println("啊。。我被增强了");
    result = method.invoke(new Dog(),objects);
    }
    return result;
    }
    });
    dog.run();
    }
    }
  2. 构造实现类的方式

    java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class MyCgLibTest_Outermpl {
    public static void main(String[] args) {
    Dog dog = (Dog)Enhancer.create(Dog.class,new MyMethodInterceptor());
    dog.run();
    }
    }

    class MyMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    Object result = null;
    if ("run".equals(method.getName())){
    System.out.println("啊。。我被增强了");
    result = method.invoke(new Dog(),objects);
    }
    return result;
    }
    }

一些问题

如果向下转型为实现类,那么会报错如下,所以正确的方法是转换为接口类型:

java
1
2
Exception in thread "main" java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to com.lucfzy.DynamicProxyTest.Dog
at com.lucfzy.DynamicProxyTest.MainTest.main(MainTest.java:14)
打赏
  • 微信
    微信
  • 支付宝
    支付宝