静态代理
public interface Subject { void dealTask(String taskName); } public class RealSubject implements Subject { @Override public void dealTask(String taskName) { System.out.println("Running Task:" + taskName); try { TimeUnit.MILLISECONDS.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } public class ProxySubject implements Subject { private Subject delegate; public ProxySubject(Subject delegate) { this.delegate = delegate; } @Override public void dealTask(String taskName) { long startTime = System.currentTimeMillis(); delegate.dealTask(taskName); long endTime = System.currentTimeMillis(); System.out.println("Running time:" + (endTime - startTime) + " timeMills"); } } public class SubjectStaticFactory { public static Subject getInstance(){ return new ProxySubject(new RealSubject()); } } public class Client { public static void main(String[] args) { Subject proxy=SubjectStaticFactory.getInstance(); proxy.dealTask("DBQuery by static proxy"); } }
动态代理
public class SubjectInvocationHandler implements InvocationHandler { private Object delegate; public SubjectInvocationHandler(Object delegate) { this.delegate = delegate; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); method.invoke(delegate, args); long endTime = System.currentTimeMillis(); System.out.println("Running time:" + (endTime - startTime) + " timeMills"); return null; } } public class DynProxyFactory { public static Subject getInstance() { Subject delegate = new RealSubject(); InvocationHandler handler = new SubjectInvocationHandler(delegate); Subject proxy = null; proxy = (Subject) Proxy.newProxyInstance(delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), handler); return proxy; } } public class Client { public static void main(String[] args) { Subject proxy=DynProxyFactory.getInstance(); proxy.dealTask("DBQuery by dynamic proxy"); } }
cglib代理
public class CgProxyFactory implements MethodInterceptor { private Object target; public CgProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { Enhancer en = new Enhancer(); en.setSuperclass(target.getClass()); en.setCallback(this); return en.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { long startTime = System.currentTimeMillis(); method.invoke(target, objects); long endTime = System.currentTimeMillis(); System.out.println("Running time:" + (endTime - startTime) + " timeMills"); return null; } } public class Client { public static void main(String[] args) { Subject target = new RealSubject(); RealSubject proxy= (RealSubject) new CgProxyFactory(target).getProxyInstance(); proxy.dealTask("DBQuery by cglib proxy"); } }
静态代理:代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法;容易出现大量冗余代码,扩展麻烦,代码维护复杂
动态代理:实现InvocationHandler接口,通过统一的工厂类来获取代理对象;所有函数都会经过invoke方法,可以在这里做一些操作,如日志系统、事务、拦截器、权限控制等,这就是AOP(切面编程)的原理
cglib代理:JDK动态代理需要实现接口,如果没有实现接口,可以使用cglib代理;底层是通过使用一个字节码处理框架ASM来转换字节码并生成新的类,实际上是一种动态构建子类的方法,所以代理类不能为final,方法不能为final/static
spring AOP中,依据目标对象是否存在接口实现,选择不同的代理方式