代理模式

Java原生代理模式

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class ProxyBean implements ProxyInterface{
private String filed = "This is a word for test!!";

@Override
public String proxyMethod(String word){
return "这是一句话:"+word;
}

@Override
public String proxyMethod1(String word) {
return "这是一句话:"+word;
}

public String getFiled() {
return filed;
}

public void setFiled(String filed) {
this.filed = filed;
}

}

接口:

1
2
3
4
public interface ProxyInterface {
public String proxyMethod(String word);
public String proxyMethod1(String word);
}

代理类:

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
public class ProxyHandler<T> implements InvocationHandler{
//被代理的对象
private T target;

public ProxyHandler(T target) {
this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke执行");
System.out.println(method.getName());
System.out.println("参数:"+ Arrays.toString(args));
return method.invoke(target, args);
}

public T getProxy(){
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); //获取类加载器
Class<?>[] interfaces = target.getClass().getInterfaces(); //获取类的父接口
Object o = Proxy.newProxyInstance(contextClassLoader,interfaces,this)
System.out.println(o instanceof ProxyBean); //false
System.out.println(o instanceof ProxyInterface); //true
return (T)o;
}
}

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Java原生动态代理
* 目标对象必须实现一个接口,转换的时候,只能以接口的形式转化,需要实现InvocationHandler接口
*/
public class ProxyTest {
@Test
public void testProxy() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> aClass = Thread.currentThread().getContextClassLoader().loadClass("cn.ws.proxy.ProxyBean");
ProxyBean proxyBean = (ProxyBean) aClass.newInstance();
ProxyHandler<ProxyInterface> proxyHandler = new ProxyHandler(proxyBean);
ProxyInterface proxy = proxyHandler.getProxy();
System.out.println(proxy.proxyMethod("测试"));
}
}

注:使用Java原生代理的时候,被代理的对象必须是实现一个接口,代理对象强转的时候只能被转换为被代理对象的接口形式。
结果:

1
2
3
4
invoke执行
proxyMethod
参数:[测试]
这是一句话:测试

Cglib代理

测试对象:

1
2
3
4
5
6
7
public class TestBean {
private String filed = "This is a word for test!!";

public String proxyMethod(String word){
return "这是一句话:"+word;
}
}

代理对象:

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
31
32
33
34
35
36
37
38
39
40
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
* Cglib代理
* 代理的对象(目标对象)可以不用实现接口,Spring里面集成了这个代理,代理类实现MethodInterceptor使用的时候直接使用Spring的包就可以了
* Java原生的代理类需要实现InvocationHandler这个接口,而且目标对象必须要实现一个接口才可以使用代理模式
* @param <T>
*/
public class ProxyFactory<T> implements MethodInterceptor {
//代理的目标对象
private T target;

public ProxyFactory(T target) {
this.target = target;
}

@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
String superName = methodProxy.getSuperName();
System.out.println("代理执行!");
System.out.println("执行方法:"+method.getName()+" 代理方法:"+methodProxy.getSuperName()+" 参数:"+ Arrays.toString(args));
return method.invoke(target,args);
}

public T getProxyInstance(){
//1.工具类
Enhancer en = new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理对象)
return (T)en.create();
}
}

测试方法:

1
2
3
4
5
6
7
8
9
10
11
public class ProxyTest {
@Test
public void testProxy() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> aClass = Thread.currentThread().getContextClassLoader().loadClass("cn.ws.Cglib.TestBean");
TestBean o = (TestBean)aClass.newInstance();
ProxyFactory<TestBean> proxyFactory = new ProxyFactory(o);
TestBean proxyInstance = proxyFactory.getProxyInstance();
System.out.println(proxyInstance.proxyMethod("测试"));
System.out.println(proxyInstance.getClass());
}
}

结果:

1
2
3
4
代理执行!
执行方法:proxyMethod 代理方法:CGLIB$proxyMethod$0 参数:[测试]
这是一句话:测试
class cn.ws.Cglib.TestBean$$EnhancerByCGLIB$$1d1cb9da
文章作者: C.c
文章链接: https://liquidcat.cc/代理模式.html
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Me