@BertLee
2017-08-10T03:26:13.000000Z
字数 3193
阅读 1350
代理模式可以实现对被代理对象的间接控制,可以对被代理对象的方法进行增强,她不重写原有的方法。
代理模式基本分为3类:
- jdk静态代理: 1个代理类只能代理1个类,局限性较大。
- jdk动态代理: 1个代理类能代理多个类,要求被代理类必须要有接口,利用了反射,效率比较低。
- cglib动态代理:1个代理类能代理多个类,被代理类不需要有接口,效率较高,不能代理final的类和方法
套路:
1. 代理类要实现被代理类的接口,使代理类的方法与被代理类的保持一致。
2. 代理类要加入一个被代理类的委托对象,由客户端初始化。
3. 添加私有的增强方法。
/*** 登录接口*/public interface LoginService {public void login();}
/*** 登录接口代理对象*/public class LoginServiceProxy implements LoginService{private LoginService loginService;public LoginServiceProxy(LoginService loginService){this.loginService = loginService;}public void login() {preLogin();loginService.login();postLogin();}private void preLogin(){System.out.println("=====登录前认证校验=====");}private void postLogin(){System.out.println("=====登录后日志记录=====");}}
/*** 登录接口实现类*/public class LoginServiceImpl implements LoginService{public void login() {System.out.println("正在登录...");}}
/*** jdk静态代理测试*/public class JdkStaticProxyTest {@Testpublic void testJdkStaticProxy(){LoginServiceProxy loginServiceProxy = new LoginServiceProxy(new LoginServiceImpl());loginServiceProxy.login();}}
/*** 登录接口*/public interface LoginService {public void login();}
/*** 登录接口实现类*/public class LoginServiceImpl implements LoginService {public void login() {System.out.println("正在登录...");}}
/*** 登录接口代理对象*/public class ServiceInvocationHandler implements InvocationHandler {//被代理对象private Object target;public ServiceInvocationHandler(Object object){this.target = object;}private void preOperation(){System.out.println("=====执行前校验=====");}private void postOperation(){System.out.println("=====执行后记录日志=====");}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {preOperation();Object result = method.invoke(target, args);postOperation();return result;}public Object getProxy() throws Throwable {return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), this.target.getClass().getInterfaces(), this);}}
/*** jdk静态代理测试*/public class JdkDynamicProxyTest {@Testpublic void testJdkStaticProxy() throws Throwable {LoginService proxy = (LoginService) new ServiceInvocationHandler(new LoginServiceImpl()).getProxy();proxy.login();System.out.println(proxy.getClass());}}
/*** 登录类*/public class LoginServiceImpl{public void login() {System.out.println("正在登录...");}}
/*** 登录接口代理对象*/public class LoginServiceProxy implements MethodInterceptor{private Object target;public LoginServiceProxy(Object obj){this.target = obj;}public Object getInstance(){Enhancer enhancer = new Enhancer();enhancer.setSuperclass(this.target.getClass());enhancer.setCallback(this); //设置回调方法return enhancer.create(); //创建代理对象}public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {preOpteration();Object result = methodProxy.invokeSuper(o, objects);postOpteration();return result;}private void preOpteration(){System.out.println("=====执行前校验=====");}private void postOpteration(){System.out.println("=====执行后记录日志=====");}}
/*** cglib动态代理测试*/public class CglibProxyTest {@Testpublic void testCglibProxy(){LoginServiceImpl loginServiceProxy = (LoginServiceImpl) new LoginServiceProxy(new LoginServiceImpl()).getInstance();loginServiceProxy.login();}}
- 撰写本文考了不少博文,在此一并谢过。
Java代理(jdk静态代理、动态代理和cglib动态代理)
《JAVA与模式》之代理模式- 转载时,请注明出处,这是人格的一种体现。
https://www.zybuluo.com/BertLee/note/845369- 能力有限,如有纰漏,请在评论区指出,老朽虽一把年纪,必当感激涕零,泪如雨下。若有满嘴喷粪撕逼者,一律拉黑、举报。