由程序员创建或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。
优点:不依赖于其它的类,实现简单。
缺点:当接口或抽象类添加方法时,需要修改相应的代理类。
Sample:
(1)、定义一个接口或者抽象类,这边定义一个接口
interface HelloWorld{ void say(); }
(2)、实现类
public class HelloWorldImp implements HelloWorld{ public void say(){ System.out.println("Hello,World!"); } }
(3)、静态代理类
public class HelloWorldProxy implements HelloWorld{ private HelloWorld helloWorld; public HelloWorldProxy(HelloWorld helloWorld){ this.helloWorld = helloWorld; } public void say(){ System.out.println("do something..."); helloWorld.say(); System.out.println("do something..."); } }
(4)、测试类
public class TestHelloWorldProxy{ public static void main(String[] args) { HelloWorld helloWorld = new HelloWorldImp(); HelloWorldProxy helloWorldProxy = new HelloWorldProxy(helloWorld); helloWorldProxy.say(); } }
二、动态代理
1、JDK动态代理
JDK动态代理类的字节码在程序运行时由Java反射机制动态生成
优点:创建代理对象速度快
缺点:执行速度慢,只能对实现接口的类做代理
Sample:
接口及实现类的定义同上。
(3)、JDK动态代理类
class JDKProxy implements InvocationHandler { private HelloWorld helloWorld; public JDKProxy(HelloWorld helloWorld) { this.helloWorld = helloWorld; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do something ..."); Object result = method.invoke(helloWorld, args); System.out.println("do something ..."); return result; } public Object getProxy() { return Proxy.newProxyInstance(helloWorld.getClass().getClassLoader(), helloWorld.getClass().getInterfaces(), this); } }
(4)、测试类
public class TestJDKProxy{ public static void main(String[] args) { HelloWorld helloWorld = new HelloWorldImp(); JDKProxy handler = new JDKProxy(helloWorld); HelloWorld proxy = (HelloWorld)handler.getProxy(); proxy.say(); } }
2、Cglib动态代理
Cglib是针对类来实现代理的,他的原理是对指定的目标类动态生成一个子类,并覆盖其中方法实现增强。
优点:执行速度快
缺点:创建代理对象速度慢,不能代理final类,
Sample:
接口及实现类的定义同上。
(3)、Cglib动态代理类
public class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("do something ..."); Object result = proxy.invokeSuper(obj, arg); System.out.println("do something ..."); return result; } public Object getInstance(Object target) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } }
(4)、测试类
public class TestCglibProxy{ public static void main(String[] args) { HelloWorld helloWorld = new HelloWorldImp(); CglibProxy interceptor = new CglibProxy(); HelloWorld proxy = (HelloWorld)interceptor.getInstance(helloWorld); proxy.say(); } }