java动态代理
Nov 28, 2016
代理模式, 可以只提供方法, 实际操作交给被代理对象去完成, 好处是可以在不修改原来代码基础上新增功能, 也可以优化, 当然还有等等…
简单说下java的三中代理实现
静态代理
JDK8的新特性, 接口中可以有方法体, 主要实现一个print方法
1
2
3
4
5
6
7package main.staticproxy;
public interface JDK8Tools {
public default void print(Object msg) {
System.out.println(msg);
}
}学习接口, 定义了三个方法
1
2
3
4
5
6
7
8
9
10package main.staticproxy;
public interface Study {
public abstract void studyJava();
public abstract void studyPhp();
public abstract void studyJavaScript();
}
“我”实现了学习接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17package main.staticproxy;
public class StudentOfLuowen implements JDK8Tools, Study {
public void studyJava() {
print("I love Java");
}
public void studyPhp() {
print("I'am paper");
}
public void studyJavaScript() {
print("JavaScript is very Hot!!!");
}
}
通过代理类, 代理我学习, 外面看是”代理类”在学习, 其实是”我”在学习
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31package main.staticproxy;
public class StudentProxy implements JDK8Tools, Study{
private StudentOfLuowen studentOfLuowen = null;
public StudentProxy(StudentOfLuowen studentOfLuowen) {
this.studentOfLuowen = studentOfLuowen;
}
public void studyJava() {
print("proxy luowen Study JavaStart");
studentOfLuowen.studyJava();
print("proxy luowen Study JavaEnd");
}
public void studyPhp() {
print("proxy luowen Study PHP start");
studentOfLuowen.studyPhp();
print("proxy luowen Study PHP end");
}
public void studyJavaScript() {
print("proxy luowen Study JavaScript start");
studentOfLuowen.studyJavaScript();
print("proxy luowen Study JavaScript end");
}
}
测试类
1
2
3
4
5
6
7
8
9
10package main.staticproxy;
public class StudentProxyTest {
public static void main(String[] args) {
StudentProxy studentProxy = new StudentProxy(new StudentOfLuowen());
studentProxy.studyJavaScript();
studentProxy.studyJava();
studentProxy.studyPhp();
}
}
JDK5 反射包中的Proxy代理对象(被代理对象一定要有接口实现, 这是硬伤)
同上JDK8Tools接口和Study接口
同上”我(StudentOfLuowen)”对象实现了 JDK8Tools, Study接口
JDK5 Proxy实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package main.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Jdk5Proxy<T> implements InvocationHandler{
private T target = null;
public T bind (T target) {
this.target = target;
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + ": invoke start!!");
Object result = method.invoke(target, args);
System.out.println(method.getName() + ": invoke end!!");
return result;
}
}JDK5 Proxy 测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15package main.jdkproxy;
import main.StudentOfLuowen;
import main.Study;
public class Jdk5ProxyTest {
public static void main(String[] args) {
Study proxy = new Jdk5Proxy<Study>().bind(new StudentOfLuowen());
proxy.studyJava();
proxy.studyJavaScript();
proxy.studyPhp();
}
}
cglib动态代理 (完美解决JDK5Proxy代理的问题)
独立的学生, 没有实现任何接口
1
2
3
4
5
6
7
8
9
10package main.cglibproxy;
public class IndependentStudent {
public void studyMath() {
System.out.println("学习数学");
}
public void studyEnglish() {
System.out.println("学习英语");
}
}CGlib代理实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package main.cglibproxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CGlibProxy<T> implements MethodInterceptor{
private T target = null;
public T bind(T target) {
this.target = target;
return (T) Enhancer.create(target.getClass(), this);
// another implement method
// 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 {
/* invokeSuper() */
return methodProxy.invokeSuper(o, objects);
}
}测试代码
1
2
3
4
5
6
7
8
9
10
11package main.cglibproxy;
public class CGlibProxyTest {
public static void main(String[] args) {
IndependentStudent independentStudent = new CGlibProxy<IndependentStudent>().bind(new IndependentStudent());
independentStudent.studyEnglish();
independentStudent.studyMath();
}
}
PS: 欢迎拍砖