1.JDK动态代理
jdk动态代理必须要借助接口才能代理对象,所以先定义接口并实现定义接口 代码如下
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public interface test1_helloworldInterface { public void sayHelloWorld();}复制代码
接口实现代码
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public class test1_helloworldImpl implements test1_helloworldInterface { @Override public void sayHelloWorld() { System.out.println("sayhelloworld"); }}复制代码
建立代理对象与真实服务对象之间的关系,然后在实现代理逻辑,因此先创建一个代理对象,这个代理对象是需要去实现import java.lang.reflect.InvocationHandler接口,他里面定义了一个invoke方法,并提供接口数组用于下挂代理对象,这一步相当关键,代码如下
package com.day1.com.test1;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * Created by leewihong on 2018/6/14. */public class jdkexampleProxy implements InvocationHandler { private Object targetImpl = null; public Object bind(Object targetImpl){ this.targetImpl = targetImpl;// 建立代理对象和真实对象之间的关系 return Proxy.newProxyInstance(targetImpl.getClass().getClassLoader(),targetImpl.getClass ().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("进入代理逻辑方法"); System.out.println("在调度真实对象之前的服务");// invoke相当于是调度了真实的方法 Object result = method.invoke(targetImpl,args); System.out.println("在调度真实对象之后的服务"); return result; }}复制代码
动态代理测试方法
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public class test1 { public static void main(String [] args){// 1.test1 jdkexampleProxy jdkexampleProxy = new jdkexampleProxy(); test1_helloworldInterface proxy = (test1_helloworldInterface) jdkexampleProxy.bind(new test1_helloworldImpl()); proxy.sayHelloWorld(); }}复制代码
动态代理测试结果
进入代理逻辑方法在调度真实对象之前的服务sayhelloworld在调度真实对象之后的服务复制代码
验证args参数是否传过去新建另外一个接口
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public interface test1_hellowordinterface2 { public void sayhelloword2(String name);}复制代码
实现类如下
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public class test1_hellowordimpl2 implements test1_hellowordinterface2{ @Override public void sayhelloword2(String name) { System.out.println(name); }}复制代码
测试代码
package com.day1.com.test1;/** * Created by leewihong on 2018/6/14. */public class test1 { public static void main(String [] args){// 1.test1 jdkexampleProxy jdkexampleProxy = new jdkexampleProxy(); test1_helloworldInterface proxy = (test1_helloworldInterface) jdkexampleProxy.bind(new test1_helloworldImpl()); proxy.sayHelloWorld();// 2.test2 test1_hellowordinterface2 proxy2 = (test1_hellowordinterface2) jdkexampleProxy.bind(new test1_hellowordimpl2 ()); proxy2.sayhelloword2("weihong"); }}复制代码
输出结果
进入代理逻辑方法在调度真实对象之前的服务sayhelloworld在调度真实对象之后的服务进入代理逻辑方法在调度真实对象之前的服务weihong在调度真实对象之后的服务Process finished with exit code 0复制代码
2.拦截器
拦截器所做的一个目的其实就是需要暴漏一个接口给外部,然后将代理和接口给绑定起来,外部只需要关注接口怎么定义和实现即可
定义拦截器接口
public interface test2_interceptor { public boolean before(Object proxy, Object target, Method method, Object [] args); public void around(Object proxy, Object target, Method method, Object [] args); public void after(Object proxy, Object target, Method method, Object [] args);}复制代码
实现拦截器接口
package com.day1.com.test1.com.test2;import java.lang.reflect.Method;/** * Created by leewihong on 2018/6/14. */public class test2_myinterceptor implements test2_interceptor { @Override public boolean before(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法前逻辑"); return false; } @Override public void around(Object proxy, Object target, Method method, Object[] args) { System.out.println("取代了了被代理对象的方法"); } @Override public void after(Object proxy, Object target, Method method, Object[] args) { System.out.println("反射方法后逻辑"); }}复制代码
在代理中绑定拦截接口
package com.day1.com.test1.com.test2;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * Created by leewihong on 2018/6/14. */public class test2_interceptorJDKProxy implements InvocationHandler { private Object target = null; private String interceptorclass = null; public test2_interceptorJDKProxy(Object target,String interceptorclass){ this.target = target; this.interceptorclass = interceptorclass; } public static Object bind(Object target,String interceptorclass){ return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass() .getInterfaces(),new test2_interceptorJDKProxy(target,interceptorclass)); } @Override public Object invoke(Object proxy,Method method, Object[] args) throws Throwable { if (interceptorclass == null){// 没有拦截器直接反射原有方法 return method.invoke(target,args); } Object result = null;// 通过反射生成拦截器 test2_interceptor test2_interceptor =(test2_interceptor) Class.forName(interceptorclass).newInstance(); if (test2_interceptor.before(proxy,target,method,args)) {// 反射原有对象方法 result = method.invoke(target,args); } else { test2_interceptor.around(proxy,target,method,args); } test2_interceptor.after(proxy,target,method,args); return result; }}复制代码
测试动态代理拦截器
package com.day1.com.test1.com.test2;import com.day1.com.test1.test1_helloworldImpl;/** * Created by leewihong on 2018/6/14. */public class test2 { public static void main(String [] args){ test2_helloword proxy = (test2_helloword) test2_interceptorJDKProxy.bind(new test2_hellowordImp(),"com.day1.com.test1.com.test2.test2_myinterceptor"); proxy.sayhelloword(); }}复制代码
得到结果
反射方法前逻辑取代了了被代理对象的方法反射方法后逻辑复制代码