静态代理比较简单,就是代理对象与被代理对象继承相同的接口,代理类负责调用被代理类(委托类)的对象的相关方法去提供具体的服务,一个代理类只能为一个接口服务,要是有很多服务的话需要开很多代理类。而动态代理则是由反射实现,可以用一个代理类实现所有的代理功能,这点是比较方便的。
先看看静态代理:
一个接口类,若干个接口实现类和一个代理类即可
接口
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