1.静态代理
2.动态代理
三个角色:目标对象,代理对象,公共接口。
目标对象和代理对象都要实现公共接口
主要是通过jdk的内置代理对象实现Proxy
1.俩关键:InvocationHandler接口 和 Proxy类
IncocationHandler是处理器接口,自己写的代理类要实现该接口并实现invoke方法
public class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return null;
}
}
该方法传入三个参数:需要代理的对象proxy,该对象中的莫个方法,以及该方法的参数
方法的四要素:1.调用方法的对象。
2.该方法
3.方法参数
4.返回结果
在自己写的类中实现公共接口,比如:
public interface OrderService {
void update(int id);
}
目标类
public class OrderServiceImpl implements OrderService{
@Override
public void update(int id) throws InterruptedException {
Thread.sleep(1234);
System.out.println("订单"+id+"修改成功!");
}
}
自定义处理器
public class MyInvocationHandler implements InvocationHandler {
private Object target;
//通过构造方法进行注入要代理的目标对象
public MyInvocationHandler(Object target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//可以进行功能增强
long begin = System.currentTimeMillis();
method.invoke(target, 1);
long end = System.currentTimeMillis();
System.out.println("耗费"+(end - begin)+"毫秒");
return null;
}
}
编写测试程序并且把要代理的对象(OrderServiceImpl) 传入
public class PublicTest {
//目标对象
OrderService target=new OrderServiceImpl();
@Test
public void OrderServiceTest() throws InterruptedException {
OrderService proxyObj = (OrderService)Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new MyInvocationHandler(target));
proxyObj.update(1);
}
}
其中Proxy.newProxyInstance()方法传入三个参数:1.要代理对象的类加载器
2.代理和目标实现的公共接口
3.自定义的代理处理器(主要是实现功能增强)
最后测试程序,
订单1修改成功。
耗费1241毫秒
进程已结束,退出代码0
总结:使用动态代理好处就是可以保护目标对象,实现功能增强,还可以实现代码复用