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++++++