JDK代理
来源:互联网 发布:淘宝网老是要重新登录 编辑:程序博客网 时间:2024/05/21 05:06
什么是代理,什么是静态代理,什么是动态代理,什么是代理类(增强实现类),什么是委托类,为什么需要代理,代理用在什么地方等等。
刚开始接触代理时,总会有这样那样的疑问。现在我们看一下静态代理的代码,学习静态代理,更有利我们理解这些概念问题。
定义一个接口:(共同接口)
package three.day.proxy.staticproxy;
public interface ReadableInterface {
public void read();
}
定义接口实现类:(委托类,真正业务逻辑实现的地方)
接口实现类一:
package three.day.proxy.staticproxy;
public class Reader implements ReadableInterface {
@Override
public void read() {
System.out.println("reader is reading a book");
}
}
接口实现类二:
package three.day.proxy.staticproxy;
public class Student implements ReadableInterface {
@Override
public void read() {
System.out.println("student is reading a book");
}
}
说明:在平时,定义好这些实现类后,我们就可以在我们需要的地方通过new实现类,就可以调用相应的服务,如:
//临时说明加入的代码:
public static void main(String[] args){
ReadableInterface reader = new Reader();
reader.read();
ReadableInterfacestudent = new Student();
student .read();
}
到现在,貌似我们并不需要代理的功能,就已经实现我们的需求了。
的确,你不是做框架的,使用以上代码貌似已经满足我们的需求了,顶多就把以上操作封装到一个方法中。
但是,你想想,假设你是一个开发框架的,如spring,你开发的服务中需要的参数是由外部传进来的,这样你就不能确定的说
外部传进了一个什么类型的对象,你必须考虑兼顾所有传进来的类型的可能性,所以这里就回答咯为什么需要代理,以及代理用在什么地方。
定义代理类:
package three.day.proxy.staticproxy;
public class ProxyReader implements ReadableInterface{
private ReadableInterface reader;
public ProxyReader(){}
public ProxyReader(ReadableInterface reader){
this.reader = reader;
}
@Override
public void read() {
this.reader.read();
}
}
我们看到代理类ProxyReader 与委托类(Reader Student)都实现了同样的接口ReadableInterface,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等等等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
有以上代码:我们可以总结一下,什么是静态代理,即接口,实现类,代理类都是由我们这些程序猿写好,编译成对应的 .class 文件。
下面写代码应用上静态代理:
package three.day.proxy.staticproxy;
public class Main {
public static void main(String[] args) {
Reader reader = new Reader();
Student student = new Student();
ProxyReader proxyReader = new ProxyReader(reader);
ProxyReader proxyStudent = new ProxyReader(student);
proxyReader.read();
proxyStudent.read();
}
}
另外,这里都使用上了接口,除了具备Java中多态的特性,也是为了实现代理的功能,
在动态代理中,还要求委托类(实现类)不能是final的,这将在动态代理中继续探讨。
动态代理:
与静态代理相比,动态代理中的代理类就不是实现写好,而是通过Java的反射技术动态生成的,所以叫动态代理。
在jdk的动态代理中,主要使用到Proxy类和InvocationHandler接口动态获取一个动态代理类或者动态代理类实例对象。
下面,我将带着大家怎么使用Proxy类和InvocationHandler接口动态获取一个动态代理类或者动态代理类实例对象,这里会使用到反射技术。
定义公用接口:
package three.day.proxy.staticproxy;
public interface ReadableInterface {
public void read();
}
定义实现类:
package three.day.proxy.staticproxy;
public class Student implements ReadableInterface {
@Override
public void read() {
System.out.println("student is reading a book");
}
}
实现动态代理代码:
package three.day.proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import three.day.proxy.staticproxy.ReadableInterface;
import three.day.proxy.staticproxy.Student;
public class DynamicProxyDemo01 {
public static void main(String[] args){
final Student student = new Student();//委托类对象
ClassLoader loader = student.getClass().getClassLoader();
System.out.println("ClassLoader = " + loader);
Class<?>[] interfaces = student.getClass().getInterfaces();
System.out.println(interfaces[0]);
InvocationHandler handler = new InvocationHandler() {//实现匿名代理类对象调用方法的接口,也就是说,proxy对象会调用invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("逻辑事务执行前控制代码");
//执行对象student的read方法,read方法的参数为args,retVal 是执行read方法的值,我定义的read方法没返回值,所以retVal为null
Object retVal = method.invoke(student, args);
System.out.println("逻辑事务执行后处理代码");
return retVal ;
}
};
Object proxy = Proxy.newProxyInstance(loader, interfaces, handler);
System.out.println(proxy.getClass());
ReadableInterface stu = (ReadableInterface) proxy;//之所以要使用接口,这里可以看出为什么了
stu.read();//通过代理对象调用read方法,而不是直接调用student .read(),这就是用于不用代码的区别:在invoke方法中可以做很多处理
}
}
下面再通过反射技术实现动态代理:
package three.day.proxy.dynamicproxy;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import three.day.proxy.staticproxy.ReadableInterface;
import three.day.proxy.staticproxy.Student;
public class DynamicProxyDemo02 {
public static void main(String[] args) throws SecurityException, NoSuchMethodException,
IllegalArgumentException, InstantiationException, IllegalAccessException,
InvocationTargetException{
final Student student = new Student();
ClassLoader loader = student.getClass().getClassLoader();
Class<?>[] interfaces = student.getClass().getInterfaces();
Class clazz = Proxy.getProxyClass(loader, interfaces);
System.out.println(clazz);
Constructor[] contructors = clazz.getConstructors();
for(Constructor c : contructors){
System.out.println(c);
}
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
ReadableInterface proxyStudent = (ReadableInterface)constructor.newInstance(new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("事务执行前代码");
Object retVal = method.invoke(student, args);
System.out.println("事务执行后代码");
return retVal;
}
});
proxyStudent.read();
}
}
下面使用cglib实现动态代理:
cglib-nodep-2.1_3.jar可在spring的jar中找到。
下面看源代码:
package three.day.proxy.dynamicproxy.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibReaderProxy implements MethodInterceptor {
private Object target;
public Object getProxy(Object target){
this.target = target;
//定义一个增强实现类对象
Enhancer enhancer = new Enhancer();
//定义该增强实现要继承的父类,所以父类不能是final的
enhancer.setSuperclass(this.target.getClass());
//设置增强实现类的回调方法
enhancer.setCallback(this);
return enhancer.create();//创建代理对象
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("事务前逻辑处理");
Object retVal = proxy.invokeSuper(obj, args);
System.out.println("事务后逻辑处理");
return retVal;
}
}
package three.day.proxy.dynamicproxy.cglib;
import three.day.proxy.staticproxy.ReadableInterface;
import three.day.proxy.staticproxy.Student;
public class CglibProxyDemo01 {
public static void main(String[] args) {
CglibReaderProxy cglibReaderProxy = new CglibReaderProxy();
ReadableInterface student = new Student();
ReadableInterface proxy = (ReadableInterface)cglibReaderProxy.getProxy(student);
proxy.read();
}
}
- 顶
- 0
- 踩
- 0
- 猜你在找
- JDK代理
- JDK代理
- jdk代理
- jdk代理
- JDK Proxy代理&CGLIB代理
- 代理模式,JDK动态代理
- Java动态代理--jdk代理
- 代理模式-JDK动态代理
- JDK中的动态代理
- JDK动态代理
- JDK动态代理
- JDK动态代理
- jdk动态代理(暂)
- JDK动态代理
- JDK动态代理实例
- jdk 动态代理
- JDK动态代理
- JDK动态代理说明
- 深入理解Java的接口和抽象类
- mybatis配置说明
- 非平稳时间序列趋势分析
- CSS动画及特效
- 内存寻址(一)硬件寻址的基本原理:硬件中的分段和分页机制,控制寄存器CR0与CR3
- JDK代理
- java集合框架之集合体系
- 双倍数 题解
- Hello Kotlin(三)类和函数
- Framework7——如何使用路由load或back页面
- 实现Autolayout的注意事项
- "缘来在此交友网"项目前端页面总结
- Savitzky-Golay 滤波器在心电数据平滑中的应用
- 暗时间阅读心得