您的位置:首页 > 编程语言 > Java开发

Java设计模式——代理模式

2018-03-20 11:16 197 查看
常用的代理模式有两种:静态代理,动态代理,下面我们通过栗子来一 一介绍一下。
一、静态代理模式
代理模式的作用是通过代理对象来访问目标对象,优点是在不改变原对象的情况下,增加自己的一部分功能逻辑,也就是拓展功能逻辑,这也是一种重要的编程思想。

静态代理模式需要一个父类或者接口,代理类和被代理类集成同一个父类或者实现同一个接口,代理对象调用被代理对象的同一个方法来实现代理,以接口为例,首先我们创建一个接口:public interface ILogin {

void login(String userName, String passWord);

}接下来被代理类实现该接口:public class LoginTask implements ILogin {
@Override
public void login(String userName, String passWord) {
System.out.println("登录:" + userName + " " + passWord);
}
}然后代理类也实现该接口,并拓展相应逻辑,登录完成后给一个log打印提示:public class LoginTaskProxy implements ILogin {

private ILogin mLogin;

public LoginTaskProxy(ILogin login) {
this.mLogin = login;
}

@Override
public void login(String userName, String passWord) {
if (mLogin != null) {
mLogin.login(userName, passWord);
System.out.println("登录完成!");
}
}
}接下来运行代码: public static void main(String[] args) {
LoginTask loginTask = new LoginTask();
new LoginTaskProxy(loginTask).login("000", "123");
}看下log:03-19 16:49:37.481 21261-21261/lbx.myapplication I/System.out: 登录:000 123
03-19 16:49:37.481 21261-21261/lbx.myapplication I/System.out: 登录完成!这样,一个最最简单的静态代理就写完了。

二、动态代理
动态代理是通过反射来实现的,动态代理和静态代理的区别,是动态代理可以通过动态创建代理类,来实现对被代理对象的代理方法操作。动态代理是通过java.long.reflect.Proxy的newProxyInstance来实现代理的:Proxy.newProxyInstance
下面先通过一个最简单的栗子,来实现以下动态代理:
首先需要一个接口:public interface ILogin {

void login(String userName, String passWord);

}接下来调用: public static void main(String[] args) {
ILogin login = (ILogin) Proxy.newProxyInstance(
ILogin.class.getClassLoader(),
new Class[]{ILogin.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method=" + method.getName());
System.out.println("args=" + Arrays.toString(args));
return null;
}
});
              //调用login方法
              login.login("000", "111");
}
}
看下打印的log:03-20 10:00:45.700 10229-10229/lbx
4000
.myapplication I/System.out: method=login
03-20 10:00:45.700 10229-10229/lbx.myapplication I/System.out: args=[000, 111]调用login方法后,我们发现invoke方法被回调了。

好了,现在我们对动态代理有了初步的了解,接下来看下开发中常用的动态代理的用法:
首先还是ILogin接口,一样的这里就不再重复贴代码了,然后写一个被代理类LoginTask:public class LoginTask implements ILogin {

@Override
public void login(String userName, String passWord) {
System.out.println("登录:" + userName + " " + passWord);
}
}然后需要一个代理类LoginTaskProxy:
public class LoginTaskProxy implements InvocationHandler {

private Object object;

public LoginTaskProxy(Object object) {
this.object = object;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method=" + method.getName());
System.out.println("args=" + Arrays.toString(args));
return method.invoke(object, args);
}
}

接下来运行代码: public static void main(String[] args) {
LoginTaskProxy loginTaskProxy = new LoginTaskProxy(new LoginTask());
ILogin login = (ILogin) Proxy.newProxyInstance(ILogin.class.getClassLoader(), new Class[]{ILogin.class}, loginTaskProxy);
login.login("000", "111");
}
}
看下log:03-20 10:00:45.700 10229-10229/lbx.myapplication I/System.out: method=login
03-20 10:00:45.700 10229-10229/lbx.myapplication I/System.out: args=[000, 111]
03-20 10:00:45.700 10229-10229/lbx.myapplication I/System.out: 登录:000 111同样的,我们通过代理类LoginTaskProxy代理了LoginTask的login登录,然后调用Proxy的newProxyInstance方法返回的对象执行login方法,执行了动态代理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: