代理模式主要有两种:静态代理和动态代理
代理模式——角色(三种)
抽象主题角色
代理主题角色
真实主题角色
通过代理角色获得真实角色的内容!
实现方法:
第一种,代理角色和真实角色都实现同一个接口,来实现代理;
第二种,通过实现继承来实现代理,即代理角色通过继承真实角色来重写父类的方法,从而实现代理;
下面是在用户注册前面添加的一个简单的检测逻辑:
第一种、实现统一接口的代理
RegInterface.java
package com.yw.xu; public interface RegInterface { void register(); }
Register.java
package com.yw.xu; /** * 真实角色 */ public class Register implements RegInterface{ @Override public void register(){ System.out.println("用户登录"); } }
RegisterProxy.java
package com.yw.xu; /** * 代理角色 */ public class RegisterProxy implements RegInterface{ Register reg; public RegisterProxy(Register reg){ this.reg = reg; } @Override public void register(){ System.out.println("用户名检测"); reg.register(); } }
Test.java
package com.yw.xu; public class Test { public static void main(String[] args) { RegisterProxy proxy = new RegisterProxy(new Register()); // RegisterProxy2 proxy = new RegisterProxy2(new Register()); proxy.register(); } }
第二种:使用继承方法代理
Register2.java
package com.yw.xu; /** * 真实角色 */ public class Register2{ public void register(){ System.out.println("用户登录"); } }
RegisterProxy2.java
package com.yw.xu; /** * 代理角色 */ public class RegisterProxy2 extends Register2{ Register reg; public RegisterProxy2(Register reg){ this.reg = reg; } public void register(){ System.out.println("用户名检测"); reg.register(); } }
Test.java
package com.yw.xu; public class Test { public static void main(String[] args) { //RegisterProxy proxy = new RegisterProxy(new Register()); RegisterProxy2 proxy2 = new RegisterProxy2(new Register()); proxy2.register(); } }
上面的2种方法,就是一个简单的静态代理方法,一个通过接口方式实现,一种通过继承的方式实现!可以看出静态代理类有一个很大的缺点:当接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。
第二种、动态代理
下面是JDK的动态代理
JDK的代理通过接口实现
JDK的动态代理类:ProxyHander.java
package com.yw.xu.jdkproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ProxyHander implements InvocationHandler{ Object target; public ProxyHander(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("用户检测..."); Object obj = method.invoke(target, args); //②通过反射方法调用目标业务类的业务方法 return obj; } //创建代理实例 public Object newProxyInstance(){ return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//理解java类装载过程 } }
接口:RegInterface.java
package com.yw.xu; public interface RegInterface { void register(); }
实现接口类,里面可以包含多种方法:Register.java
package com.yw.xu; /** * 真实角色 */ public class Register implements RegInterface{ @Override public void register(){ System.out.println("用户登录"); } }
测试类
Test.java
package com.yw.xu.jdkproxy; import com.yw.xu.RegInterface; import com.yw.xu.Register; public class Test { public static void main(String[] args) { ProxyHander proxy = new ProxyHander(new Register()); RegInterface obj = (RegInterface)proxy.newProxyInstance();//obj是代理对象 obj.register(); } }
DK动态代理是依靠接口的方式来实现的,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。