java中靜態代理的完成。本站提示廣大學習愛好者:(java中靜態代理的完成)文章只能為提供參考,不一定能成為您想要的結果。以下是java中靜態代理的完成正文
運用的形式:代理形式。
代理形式的作用是:為其他對象提供一種代理以控制對這個對象的訪問。相似租房的中介。
兩種靜態代理:
(1)jdk靜態代理,jdk靜態代理是由Java外部的反射機制來完成的,目的類基於一致的接口(InvocationHandler)
(2)cglib靜態代理,cglib靜態代理底層則是借助asm來完成的,cglib這種第三方類庫完成的靜態代理使用愈加普遍,且在效率上更有優勢。
次要使用的框架:
Spring中的AOP,Struts2中的阻攔器
詳細完成:
1、定義接口和完成類
package com.example.service; public interface UserService { public String getName(int id); public Integer getAge(int id); }
package com.example.service.impl; import com.example.service.UserService; public class UserServiceImpl implements UserService { public String getName(int id) { System.out.println("------getName------"); return "cat"; } public Integer getAge(int id) { System.out.println("------getAge------"); return 10; } }
2、jdk靜態代理完成
package com.example.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyInvocationHandler implements InvocationHandler { private Object target; /** * 綁定委托對象並前往一個代理類 * * @param target * @return */ public Object bind(Object target) { this.target = target; //獲得代理對象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); //要綁定接口(這是一個缺陷,cglib補償了這一缺陷) } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("getName".equals(method.getName())) { System.out.println("------before " + method.getName() + "------"); Object result = method.invoke(target, args); System.out.println("------after " + method.getName() + "------"); return result; } else { Object result = method.invoke(target, args); return result; } } }
package com.example.jdk; import com.example.service.UserService; import com.example.service.impl.UserServiceImpl; /** * 測試類 */ public class RunJDK { public static void main(String[] args) { MyInvocationHandler proxy = new MyInvocationHandler(); UserService userServiceProxy = (UserService) proxy.bind(new UserServiceImpl()); System.out.println(userServiceProxy.getName(1)); System.out.println(userServiceProxy.getAge(1)); } }
運轉後果:
------before getName------
------getName------
------after getName------
cat
------getAge------
10
3、cglib靜態代理完成:
JDK的靜態代理機制只能代理完成了接口的類,而不能完成接口的類就不能完成JDK的靜態代理,cglib是針對類來完成代理的,他的原理是對指定的目的類生成一個子類,並掩蓋其中辦法完成加強,但由於采用的是承繼,所以不能對final修飾的類停止代理。
CGLIB的中心類:
net.sf.cglib.proxy.Enhancer – 次要的加強類
net.sf.cglib.proxy.MethodInterceptor – 次要的辦法阻攔類,它是Callback接口的子接口,需求用戶完成
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method類的代理類,可以方便的完成對源對象辦法的調用。
net.sf.cglib.proxy.MethodInterceptor接口是最通用的回調(callback)類型,它常常被基於代理的AOP用來完成阻攔(intercept)辦法的調用。這個接口只定義了一個辦法
public Object intercept(Object object, java.lang.reflect.Method method,
Object[] args, MethodProxy proxy) throws Throwable;
第一個參數是代理對像,第二和第三個參數辨別是阻攔的辦法和辦法的參數。原來的辦法能夠經過運用java.lang.reflect.Method對象的普通反射調用,或許運用 net.sf.cglib.proxy.MethodProxy對象調用。net.sf.cglib.proxy.MethodProxy通常被首選運用,由於它更快。
package com.example.cglib; import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CGLIBProxy implements MethodInterceptor { private Object target; /** * 創立代理對象 * * @param target * @return */ public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回調辦法 enhancer.setCallback(this); // 創立代理對象 return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("++++++before " + methodProxy.getSuperName() + "++++++"); System.out.println(method.getName()); Object result = methodProxy.invokeSuper(o, objects); System.out.println("++++++after " + methodProxy.getSuperName() + "++++++"); return result; } }
package com.example.cglib; import com.example.service.UserService; import com.example.service.impl.UserServiceImpl; /** * 測試CGLIB */ public class RunCGLIB { public static void main(String[] args) { CGLIBProxy cglibProxy = new CGLIBProxy(); UserService userService = (UserService) cglibProxy.getInstance(new UserServiceImpl()); userService.getName(1); userService.getAge(1); } }
運轉後果:
++++++before CGLIB$getName$0++++++
getName
------getName------
++++++after CGLIB$getName$0++++++
++++++before CGLIB$getAge$1++++++
getAge
------getAge------
++++++after CGLIB$getAge$1++++++