代理模式提供了对目标对象另外的访问方式,即通过代理对象访问目标对象,可以在目标对象的基础上增加额外的功能。
代理模式分为静态代理和动态代理。
java静态代理:
public class StaticProxy implements IUser{ private IUser target; public StaticProxy(IUser target){ this.target = target; } @Override public void add(String name){ //可以扩展原方法 if(name.endsWith("end")){ return; } target.add(name); } }
java动态代理模式主要分为jdk代理和cglib代理,动态代理在程序运行时,由反射机制动态生成。
spring的aop用的就是动态代理实现的。
cglib代理:需要实现net.sf.cglib.proxy.MethodInterceptor接口
public interface IUser { public void add(String name); }
public class UserDAO implements IUser{ @Override public void add(String name) { System.out.println("add user:" + name); } }
public class ObjectProxy implements MethodInterceptor{ private Object target; public Object getInstance(Object target){ this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { return method.invoke(target,objects); } }
public class CglibTest { public static void main(String[] args) { IUser userDAO = new UserDAO(); UserDAO proxyUserDAO = (UserDAO) new ObjectProxy().getInstance(userDAO); proxyUserDAO.add("jack"); } }
jdk代理:目标对象必须实现接口,newProxyInstance()第二个参数为目标对象的接口
public class JdkProxy { private Object target; public JdkProxy(Object target){ this.target = target; } public Object getInstance(){ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target,args); } }); } }
public static void main(String[] args) { IUser userDAO = new UserDAO(); IUser userProxy = (IUser) new JdkProxy(userDAO).getInstance(); userProxy.add("jack"); }