Java动态代理与反射详解
首先我得先请大家不要误会,博客园说转载的文章放在文章分类里,原创的文章用随笔写,我开先还以为随笔是拿来写抒情文的(滑稽),后来才发现不是这样的,但是自己所有的文章都在文章分类里了,又懒得搬运,所以我就用js重定向了一下。所以现在标题栏里进来的都是文章分类哦,大部分都是自己原创的,转载会注明转载的url。
废话不多说,今天我想来聊一下java里的反射和动态代理的问题,因为这两个东西实在撩人,而且动态代理百度几乎都是千篇一律,今天我写这篇博文希望能帮助大家,顺便也是为了巩固自己,毕竟自己也折腾了好久。
先来看看反射。
java里的class文件加载分为两种情况,一种就是类型是编译器已知的,这种文件的.class文件在编译的时候,编译器会把.class文件打开检查,但是注意不是加载哦,第二种就是我们可能是从别的地方获取到了一个引用,然后动态的把这个未知类型的引用的对象的.class文件加载进jvm虚拟机里。
那么我们称前者为RTTI,即Run- Time Type Identification 运行时类型识别,有的人把RTTI翻译成 Run - Time Type Information ,我个人认为是不对的,因为我觉得它概括的不够全面,所以我建议大家把I 翻译成Identification更容易理解。
我们称后者为“反射”,这对于正在学习JAVA的人来说可是一个新的名词,但反射也是作为一个java的核心技术的存在。下面就来看看反射究竟有多重要吧。
反射
在java里提供了一个叫做reflect的库,这个库里封装了Method,Constructor,field,Proxy,InvocationHandler 等类,这些类的API在我们学习反射会很有帮助。
反射最大的作用就在于我们可以不在编译时知道某个对象的类型,而在运行时得到。同时我们只需要得到我们想得到的类的名字即可(如果不在一个包,必须写完整的名字包括包名)。
package com.bike;
import java.lang.reflect.*;
public class Main {
public static void main(String[] args) throws Exception{
//返回A的构造方法
Constructor c = A.class.getConstructor();
//返回A类的所有为public 声明的构造方法
Constructor[] cons = A.class.getConstructors();
//返回A类所有的构造方法,包括private
Constructor[] cons2 = A.class.getDeclaredConstructors();
//返回A类的第一个public 方法
Method m = A.class.getMethod("say");
//执行
m.invoke(A.class.newInstance(), null);
//返回A类所有的public 方法
Method[] ms = A.class.getMethods();
//返回A类所有的方法,包括private
Method[] allMs = A.class.getDeclaredMethods();
//返回A类的public字段
Field field = A.class.getField("i");
System.out.println(field.get(A.class.newInstance()));
//返回A类的static 字段
System.out.println(field.get(null));
}
}
class A{
public int i = 1;
public static int b = 2;
public A(){
System.out.println("无参构造");
}
private A(String s){
System.out.println("有参构造"+s);
}
public void say(){
System.out.println("say");
}
}
这里我只是简单的把API罗列了一下,大家可以自己动手试试,我这里就不再去描述了。
通过上面的例子我们可以看出我们只用知道一个类的名字便可以得知它内部方法和字段,那么这里已经强烈的体现到了反射的作用。只是我这里做例子的时候把A作为了自己内部包的一个类,而在实际开发中,你可能是跨包的,所以你必须要写上全名才行。
关于.class类字面常量的知识请参照我的上一篇博文:http://www.cnblogs.com/haodawang/articles/5954368.html
代理
接下来我们来看一下代理。
代理可以帮助我们进行很好的封装,使底层的代码能够有效的隐藏起来。
为了区别,我们先来看看静态代理吧。
public class Main2 {
//这里传入的是接口类型的对象,方便向上转型,实现多态
public static void consumer(ProxyInterface pi){
pi.say();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
consumer(new ProxyObject());
}
}
//代理接口
interface ProxyInterface{
public void say();
}
//被代理者
class RealObject implements ProxyInterface{
//实现接口方法
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("say");
}
}
//代理者
class ProxyObject implements ProxyInterface{
@Override
public void say() {
// TODO Auto-generated method stub
//dosomething for example
System.out.println("hello proxy");
new RealObject().say();
System.out.println("this is method end");
}
}
output:
hello proxy
say
this is method end
这就是静态代理,理解这个应该不难。
下面我们再来看看动态代理
import java.lang.reflect.*;
public class Main {
static void customer(ProxyInterface pi){
pi.say();
}
public static void main(String[] args){
RealObject real = new RealObject();
ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));
customer(proxy);
}
}
interface ProxyInterface{
void say();
}
//被代理类
class RealObject implements ProxyInterface{
public void say(){
System.out.println("i'm talking");
}
}
//代理类,实现InvocationHandler 接口
class ProxyObject implements InvocationHandler{
private Object proxied = null;
public ProxyObject(){
}
public ProxyObject(Object proxied){
this.proxied = proxied;
}
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
System.out.println("hello");
return arg1.invoke(proxied, arg2);
};
}
可以看到动态代理的代理类是实现了一个InvocationHandler的接口,我们通过reflect.Proxy的类的newProxyInstance方法就可以得到这个接口的实例,然后再来作为参数传递进去,这里每一个在代理类上处理的东西也会被重定向到调用处理器上。
至于动态代理和静态代理的区别,即动态代理是动态的创建代理和动态的处理方法的,这也是反射的一个重要体现之处。
Java动态代理与反射详解的更多相关文章
- 5.java动态代理、反射
1.java动态代理.反射(IDEA导入JUnit4) 1.1.反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等 1.2.反射代码 import java.io.Serializa ...
- Java 动态代理与反射机制
java动态代理必须的两个类与两个接口: 首先需要有一个接口(委托者需要实现该接口的方法)示例如下: <pre name="code" class="html&qu ...
- Java基础13:反射详解
本节主要介绍Java反射的原理,使用方法以及相关的技术细节,并且介绍了关于Class类,注解等内容. 具体代码在我的GitHub中可以找到 https://github.com/h2pl/MyTech ...
- Java动态代理和反射机制
反射机制 Java语言提供的一种基础功能,通过反射,我们可以操作这个类或对象,比如获取这个类中的方法.属性和构造方法等. 动态代理:分为JDK动态代理.cglib动态代理(spring中的动态代理). ...
- Mybatis mapper动态代理的原理详解
在开始动态代理的原理讲解以前,我们先看一下集成mybatis以后dao层不使用动态代理以及使用动态代理的两种实现方式,通过对比我们自己实现dao层接口以及mybatis动态代理可以更加直观的展现出my ...
- 详解java动态代理机制以及使用场景
详解java动态代理机制以及使用场景 https://blog.csdn.net/u011784767/article/details/78281384 深入理解java动态代理的实现机制 https ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
- JAVA动态代理详解
1.什么是代理 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 2.什么是动态代理 在程 ...
- java动态代理使用详解
我们都知道AOP的原理就是java的动态代理机制,下面我就对java的动态代理机制进行学习与总结 java动态代理的实现有两个重要的类: Proxy:类 作用就是用来动态创建一个代理对象的类 Invo ...
随机推荐
- saxon 处理xslt
下载saxon : https://sourceforge.net/projects/saxon/?source=typ_redirect 下载后拿到: saxon9he.jar 运行CMD: C:\ ...
- Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(二)--node解析与环境搭建
前言 本来开始写博客的时候只是想写一下关于MongoDB的使用总结的,后来觉得还不如干脆写一个node项目实战教程实战.写教程一方面在自己写的过程中需要考虑更多的东西,另一方面希望能对node入门者有 ...
- [BZOJ2639]矩形计算
[BZOJ2639]矩形计算 题目大意: 给定一个\(n\times m(n,m\le200)\)的矩阵.\(q(q\le10^5)\)次询问,每次询问一个子矩阵中所有数字出现次数的平方和. 思路: ...
- django常用命令
model 创建表的命令 (1): python manage.py makemigrations (2): python manage.py migrate 创建一个project项目 django ...
- Synchronized、lock、volatile、ThreadLocal、原子性总结、Condition
http://blog.csdn.net/sinat_29621543/article/details/78065062
- 在AngularJS中使用谷歌地图把当前位置显示出来
如何使用谷歌地图把当前位置显示出来呢? --在html5中,为我们提供了navigator.geolocation.getCurrentPosition(f1, f2)函数,f1是定位成功调用的函数, ...
- windows Server 2008 R2 TFS2010的备份
1.首先要安装一个工具Power Tools,点击安装,然后下一步就可以了. 2.安装完之后重新打开TFS管理控制台 点击Create Backup Plan 点击下一步,它会导航到第一个页面,在这个 ...
- Java代码质量改进之:使用ThreadLocal维护线程内部变量
在上文中,<Java代码质量改进之:同步对象的选择>,我们提出了一个场景:火车站有3个售票窗口,同时在售一趟列车的100个座位.我们通过锁定一个靠谱的同步对象,完成了上面的功能. 现在,让 ...
- Java SPI机制学习笔记
最近在阅读框架源代码时,常常看到 SPI 的子包, 忍不住查了下: Service Provider Interface : 服务提供接口. JavaSPI 实际上是“基于接口的编程+策略模式+配置文 ...
- MSVC 12: compiler error in boost/type_traits/common_type.hpp
来自: https://svn.boost.org/trac10/ticket/11885 MSVC 12: compiler error in boost/type_traits/common_ty ...