那时候还小,只记得代理模式就是 daili 给 SchoolGirl 送了洋娃娃,送了花,还送了巧克力…
代理模式是在访问对象时引入一定程度的间接性,这种间接性让我们可以趁机完成许多想要的功能.代理模式的特征是代理类和委托类有同样的接口,代理类主要负责为委托类预处理消息,过滤消息,把消息转发给委托类,以及事后处理消息等.代理类对象和委托类对象关联,代理类对象是通过调用委托类的对象的相关方法提供特定的服务.
代理类如何被创建,如何被调用,如何默默调用了委托类…一系列问题都需要我们弄明白,下面我们来看看代理究竟是如何实现的.
代理分为静态代理和动态代理.
为其它对象提供一种代理以控制对这个对象的访问.之所以称之为静态,是因为程序员或特定工具在编程时已经创建了代理类,之后编译成字节码文件.在程序运行前,代理类的.class文件已经存在了.
业务接口类:
package com.tgb.staticproxy;
public interface UserManager {
public void addUser(String userId,String userName);
public String queryUser(String userId);
}
实现类:
package com.tgb.staticproxy;
public class UserManagerImpl implements UserManager {
@Override
public void addUser(String userId, String userName) {
try {
System.out.println("UserManagerImpl.addUser() userId---" + userId);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException();
}
}
@Override
public String queryUser(String userId) {
System.out.println("UserManagerImpl.queryUser() userId---" + userId);
return "转折";
}
}
代理类:
package com.tgb.staticproxy;
public class UserManagerImplProxy implements UserManager {
private UserManager userManager;
public UserManagerImplProxy(UserManager userManager){
this.userManager=userManager;
}
public void addUser(String userId,String userName){
try {
System.out.println("start--addUser()--userId--" + userId);
userManager.addUser(userId, userName);
System.out.println("success");
} catch (Exception e) {
e.printStackTrace();
System.out.println("error");
}
}
public String queryUser(String userId){
return null;
}
}
客户端:
package com.tgb.staticproxy;
public class Client {
public static void main(String[] args){
UserManager userManager=new UserManagerImplProxy(new UserManagerImpl());
userManager.addUser("1001","转折");
}
}
运行结果:
在程序运行时,运用反射机制动态创建代理类,不需要程序员编写源代码.动态代理简化了编程工作,提高了系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类.说到底,java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力.
具体说来,JDK动态代理中包含一个Proxy类和一个InvocationHandler接口.
通过Proxy类为一个或多个接口动态地生成实现类,其方法是
public static ObjectnewProxyInstance(ClassLoader loader, Class<?>[] interfaces,
InvocationHandler h) throws IllegalArgumentException{}
通过InvocationHandler接口,调用实现类的方法,从而完成最终操作.其方法是
public interfaceInvocationHandler {
public Objectinvoke(Object proxy,Method method,Object[] args) throws Throwable;
}
业务接口类:
package com.tgb.Dynamicproxy;
public interface UserManager {
public String Query(String userId);
}
实现类:
package com.tgb.Dynamicproxy;
public class UserManagerImpl implements UserManager{
@Override
public String Query(String userId) {
System.out.println("UserManagerImpl.Query()---userId--" + userId);
return "转折";
}
}
在静态代理中,一个代理类只能为一个接口提供代理,这样的话,我们开发过程中需要写N多个代理类,而且它们间只有调用的方法不一样而已.于是,我们希望只用一个代理类就完成全部的代理功能.在动态代理中,我们没有写好确定的代理类,而是有一个下面的类.
产生代理的类:
package com.tgb.Dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserManagerImplProxy implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy,Method method,Object[] args)
throws Throwable{
System.out.println("start--" + method.getName());
for(int i=0;i<args.length;i++){
System.out.println(args[i]);
}
Object ret=null;
try {
ret=method.invoke(targetObject, args);
System.out.println("success--" + method.getName());
} catch (Exception e) {
e.printStackTrace();
System.out.println("error--" + method.getName());
}
return ret;
}
}
客户端:
package com.tgb.Dynamicproxy;
public class Client {
public static void main(String[] args){
UserManagerImplProxy userManagerImplProxy=new UserManagerImplProxy();
UserManager userManager=(UserManager)userManagerImplProxy.newProxyInstance(new UserManagerImpl());
String userName=userManager.Query("1001");
System.out.println("userName--" + userName);
}
}
运行结果:
JDK动态代理的最大缺点是,它依靠接口实现,如果有的类没有实现接口,那么,它是不能使用JDK代理的.这个就是另一种动态代理----cglib动态代理了.
总结: 学习不是一条直线,温故而知新,是收获的时候了.
原文:http://blog.csdn.net/zhuanzhe117/article/details/44314207