静态代理
- 静态代理其实就是在程序运行之前,提前写好被代理方法的代理类,编译后运行。
- 在程序运行之前,class已经存在。
下面我们实现一个静态代理demo:
步骤
- 创建一个目标接口
- 目标接口实现类
- 写一个代理类实现目标接口,初始化时将目标放入
- 最后写一个测试类测试即可
代码
package Proxy;
/**静态代理*/
//测试类
public class StaticProxy {
public static void main(String[] args) {
TargetImpl target = new TargetImpl();
Proxy proxy = new Proxy(target);
System.out.println(proxy.execute());
}
}
//目标接口
interface Target{
String execute();
}
//目标实现类
class TargetImpl implements Target{
//重写方法
@Override
public String execute() {
System.out.println("目标被执行");
return "execute";
}
}
//代理类
class Proxy implements Target{
//定义目标属性
private Target target;
//构造函数,参数为目标
public Proxy(Target target){
this.target=target;
}
@Override
public String execute() {
System.out.println("代理类执行");
//执行目标接口的方法
String res = this.target.execute();
return res;
}
}
运行结果
代理类执行
目标被执行
execute
静态代理需要针对被代理的方法提前写好代理类,如果被代理的方法非常多则需要编写很多代码,因此,对于上述缺点,通过动态代理的方式进行了弥补。
动态代理
动态代理主要是通过反射机制,在运行时动态生成所需代理的class.
步骤
-
写一个目标接口和对应的目标实现类
-
代理处理类
- 目标属性
- 构造方法
- 实现InvocationHandler,重写invoke方法
-
测试:
-
实例被代理类
-
实例代理处理类
-
Proxy.newProxyInstance(被代理类的加载器,被代理类接口,代理处理类实例)生成代理类
-
代理类实现方法
-
package Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*测试类*/
public class DynamicProxyDemo {
public static void main(String[] args) {
//实例化目标实现类
TargetImpl2 target = new TargetImpl2();
//实例化代理处理类,将target放入参数
DynamicProxyHandler handler = new DynamicProxyHandler(target);
//使用reflect包下的Proxy.newProxyInstance新建动态代理类
//参数:类加载器,接口,处理类
Target2 proxySubject = (Target2) Proxy.newProxyInstance(TargetImpl2.class.getClassLoader(), TargetImpl2.class.getInterfaces(), handler);
//代理类直接方法
String res = proxySubject.execute();
System.out.println(res);
}
}
/*目标类*/
interface Target2{
String execute();
}
/*目标实现类*/
//实现Target接口
class TargetImpl2 implements Target2{
@Override
public String execute() {
System.out.println("目标类被执行");
return "target-execute";
}
}
/*代理处理类*/
//实现InvocationHandler接口
class DynamicProxyHandler implements InvocationHandler {
//定义目标类
private Target2 target2;
//构造方法
public DynamicProxyHandler(Target2 target2){
this.target2=target2;
}
//重写invoke方法,
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("=====before=====");
Object res = method.invoke(target2, args);
System.out.println("=====after=====");
return res;
}
}
- 无论是动态代理还是静态带领,都需要定义接口,然后才能实现代理功能。
- 这同样存在局限性,因此,为了解决这个问题,出现了第三种代理方式:cglib代理。