相反,如果代理类程序运行前并不存在,在程序运行时,运用反射机制动态创建而成(无需手工编写代理类源码),那就是今天要说的动态代理了。
2、实现原理
和动态代理有关的有两个类
1)、interface InvocationHandler
Object invoke(Object proxy, Method method, Object[] args)用来代理我们要做的N多事情。
2)、class Proxy
真正表示动态代理的类,提供两个静态方法:
Class> getProxyClass(ClassLoader loader, Class>[] interface)用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,用来冒充真实的对象。
Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h)产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(...)方法
3)、代理图
3、代码展示
1)、UserManager:
public interface UserManager {
public void addUser(String userId,String userName);
public void delUser(String userId);
public void modifyUser(String userId,String userName);
public String QueryUser(String userId);
}
2)、UserManagerImpl:public class UserManagerImpl implements UserManager { @Override public void addUser(String userId, String userName) { System.out.println("UserManagerImpl.addUser()"); } @Override public void delUser(String userId) { System.out.println("UserManagerImpl.delUser()"); } @Override public void modifyUser(String userId, String userName) { System.out.println("UserManagerImpl.modifyUser()"); } @Override public String QueryUser(String userId) { System.out.println("UserManagerImpl.QueryUser()"); return "zhangsan"; } }
3)、UserManagerImpl的动态代理:public class LogHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObject){ this.targetObject=targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("start-->>"+ method.getName()); for (int i=0;i
>"+ method.getName()); }catch(Exception e){ e.printStackTrace(); System.out.println("error-->>"+ method.getName()); throw e; } return ret; } } 4)、客户端调用:
public static void main(String[] args) { LogHandler logHandler=new LogHandler(); UserManager userManager=(UserManager)logHandler.newProxyInstance(new UserManagerImpl()); //userManager.addUser("1", "zhangsan"); String userName=userManager.QueryUser("1"); System.out.println("userName:"+userName); }