首先你要明白为什么要创建代理???
例如:我们看下面这张图我们发现,有很多重复的代码,我们就可以创建代理,让代理帮我们干这些事情。
1.想要创建代理,我们就要为这个类写一个接口
public interface UserService {
void login(String loginName,String passWord) throws Exception;
void deleteUsers() throws Exception;
String[] selectUsers() throws Exception;
}
2.让想要生成代理的这个类(UserServiceImpl)实现这个接口(UserService)。(既然要实现代理类,那我们那些冗余的代码就可以省略)
public class UserServiceImpl implements UserService{
@Override
public void login(String loginName, String passWord) throws Exception {
System.out.println("完成登录");
Thread.sleep(1000);
}
@Override
public void deleteUsers() throws Exception {
System.out.println("成删除1000个用户");
Thread.sleep(1000);
}
@Override
public String[] selectUsers() throws Exception {
System.out.println("共查询出三个用户");
String[] names={"阿九阿九", "解放东路", "即可"};
Thread.sleep(1500);
return names;
}
}
3.实现代理类,我们写一个静态方法来实现,方法的参数为要实现代理的这个类(UserServiceImpl),返回值为我们写的这个接口(UserService)。
public class ProxyUtil {
public static UserService creatProxy(UserService userService) {
/*ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)*/
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(ProxyUtil.class.getClassLoader(),
new Class[]{UserService.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals("deleteUsers") || method.getName().equals("login") ||
method.getName().equals("selectUsers")) {
long ss = System.currentTimeMillis();
Object rs= method.invoke(userService,args);
long ee=System.currentTimeMillis();
System.out.println(method.getName()+"耗时:"+(ee-ss));
return rs;
}else {
Object rs = method.invoke(userService, args);
return rs;
}
}
}
);
return userServiceProxy;
}
}
注意:UserService userServiceProxy = (UserService) Proxy.newProxyInstance()
①Proxy这是Java为我们写好的实现类,我们要选择反射包下的这个类
②Proxy.newProxyInstance();Proxy有一个静态方法newProxyInstance(),实现这个方法我们就得到了一个代理对象。
③因为这个对象的返回类型是Object类型所以我们要强制转换为接口类型(UserService)
④这里我们要以接口作为返回值类型来接收代理产生的对象UserService userServiceProxy=
Proxy.newProxyInstance()要写三个参数。
参数一(ClassLoader loader):一般用当前类的类加载器在调用getClassLoader()这个方法
参数二(Class<?>[] interfaces,):要new一个数组将接口作为元素写进去
参数三(InvocationHandler h):inInvocationHandler是一个接口,我们要new一个内部类来实现这个接口
4.测试类:
public class Test {
public static void main(String[] args) throws Exception {
UserService service=ProxyUtil.creatProxy(new UserServiceImpl());
service.login("aaa","kkk");
System.out.println("----------");
service.deleteUsers();
System.out.println("----------" +
"");
service.selectUsers();
}
}
就实现了整个动态代理。