静态代理比较简单,就是代理对象与被代理对象继承相同的接口,代理类负责调用被代理类(委托类)的对象的相关方法去提供具体的服务,一个代理类只能为一个接口服务,要是有很多服务的话需要开很多代理类。而动态代理则是由反射实现,可以用一个代理类实现所有的代理功能,这点是比较方便的。
先看看静态代理:
一个接口类,若干个接口实现类和一个代理类即可
接口
package proxy; public interface Women { public void eat(); public void play(); }
接口实现类一
package proxy; public class Lily implements Women{ @Override public void eat() { System.out.println("i'm Lily,i love eat banana"); } @Override public void play() { System.out.println("i'm Lily,i love swimming"); } }
接口实现类二
package proxy; public class Juli implements Women{ @Override public void eat() { System.out.println("i'm Juli,i love eat banana"); } @Override public void play() { System.out.println("i'm Juli,i love swimming"); } }
代理类
package proxy; public class Proxy implements Women{ private Women women; public Proxy(){ this.women=new Lily();//设一个代理的默认值 } public Proxy(Women women){ this.women=women; } @Override public void eat() { this.women.eat(); } @Override public void play() { this.women.play(); } }
测试
package proxy; public class StaticProxyTest { public static void main(String[] args) { Proxy p; p=new Proxy(); p.eat(); p.play(); p=new Proxy(new Juli()); p.eat(); p.play(); } }
测试结果
i'm Lily,i love eat banana i'm Lily,i love swimming i'm Juli,i love eat banana i'm Juli,i love swimming
动态代理的话主要有两种实现方式,一种是jdk动态代理实现,一种是cglib代理。JDK动态代理只能针对实现了接口的类生成代理,CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,
主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。
先看看jdk代理
代理类
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler{ private Women women; public JdkProxy(Women women){ this.women=women; } public static Women newProxyInstance(Women women){ return (Women) Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), new Class<?>[] { Women.class }, new JdkProxy(women)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(women, args); } }
改成通用点的
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JdkProxy implements InvocationHandler{ private Object obj; public JdkProxy(Object obj){ this.obj=obj; } public static Object newProxyInstance(Object targetObject){//传入的是类的实现接口 return Proxy.newProxyInstance(JdkProxy.class.getClassLoader(), targetObject.getClass().getInterfaces(),new JdkProxy(targetObject)); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(this.obj, args); } }
测试类
package proxy; public class JdkProxyTest { public static void main(String[] args) { Women women= JdkProxy.newProxyInstance(new Lily()); women.eat(); women.play(); } }
测试结果
i'm Lily,i love eat banana i'm Lily,i love swimming
Cglib代理类
package proxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private CglibProxy() { } public static <T extends Women> Women newProxyInstance(Class<T> targetInstanceClazz){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetInstanceClazz); enhancer.setCallback(new CglibProxy()); return (Women) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例 } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invokeSuper(obj, args); } }
改成通用点的
package proxy; import java.lang.reflect.Method; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private CglibProxy() { } public static <T extends Object> Object newProxyInstance(Class<T> targetInstanceClazz){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetInstanceClazz); enhancer.setCallback(new CglibProxy()); return (Object) enhancer.create();//返回的对象是一个封装了"实现类"的代理类,是实现类的实例 } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { return proxy.invokeSuper(obj, args); } }
测试
package proxy; public class CglibTest { public static void main(String[] args) { Women women = (Women) CglibProxy.newProxyInstance(Lily.class); women.eat(); women.play(); } }
测试结果
i'm Lily,i love eat banana i'm Lily,i love swimming