反射:运行时的类信息
反射提供在跨网络的远程平台上创建和运行对象的能力,这被称为远程调用(RMI),它允许一个java程序将对象分布到多台机器上。通过反射与一个未知类型的对象打交道。
Class类与java.lang.reflect类库一起对反射的概念进行了支持。该类库包含了Field、Method及Constructor类(每个类都实现了Member接口)。可以使用Constructor创建新的对象,用get()和set()方法读取和修改与Field对象关联的字段,用invoke()方法调用与Method对象关联的方法。另外,还可以调用getFields()、getMethods()和getConstructors()等方法,以返回表示字段、方法以及构造器的对象的数组。
动态代理:动态地创建代理,并动态地处理对所代理方法的调用
代理是基本的设计模式之一,它是你为了提供额外的或不同的操作,而插入的用来代替“实际”对象的对象。这些操作通常涉及“实际”对象的通信,因此代理通常充当着中间人的角色。
通过调用静态方法Proxy.newProxyInstance()可以创建动态代理,这个方法需要得到一个类加载器,一个你希望该代理实现的接口列表,以及InvocationHandler接口的一个实现。动态代理可以将所有调用重定向到调用处理器,因此通常会向调用处理器的构造器传递传递一个“实际”对象的引用,从而使得调用处理器在执行其中介任务时,可以将请求转发。
package com.jtchen.proxydemo;
/**
* 基础接口
*/
public interface BaseInterface {
void doSomething();
void somethingElse(String arg);
}
package com.jtchen.proxydemo;
/**
* 实际对象(被代理对象)
*/
public class RealObject implements BaseInterface{
@Override
public void doSomething() {
System.out.println("realObject doSomething");
}
@Override
public void somethingElse(String arg) {
System.out.println("realObject somethingElse: "+arg);
}
}
package com.jtchen.proxydemo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态代理调用处理器的实现类
*/
public class DyamicProxyHandler implements InvocationHandler{
/**
* 被代理对象的传入
*/
private Object proxied;
public DyamicProxyHandler(Object proxied){
this.proxied = proxied;
}
/**
* @param proxy 代理对象
* @param method 代理实现方法对应的Method对象
* @param args 调用的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("====== proxy: "+ proxy.getClass() +
", method: "+ method + ", args: "+args);
if(args != null){
for(Object arg : args){
System.out.println(" "+ arg);
}
}
return method.invoke(proxied, args);
}
}
package com.jtchen.proxydemo;
import java.lang.reflect.Proxy;
/**
* 动态代理创建测试
*/
public class DynamicProxyTest {
public static void consumer(BaseInterface baseInterface){
baseInterface.doSomething();
baseInterface.somethingElse("ProxyTest");
}
public static void main(String[] args){
RealObject realObject = new RealObject();
consumer(realObject);//直接调用
//创建代理后重新调用
BaseInterface proxy =
(BaseInterface) Proxy.newProxyInstance(BaseInterface.class.getClassLoader(),
new Class[]{BaseInterface.class},
new DyamicProxyHandler(realObject));
consumer(proxy);
}
}
输入结果
realObject doSomething
realObject somethingElse: ProxyTest
====== proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.jtchen.proxydemo.BaseInterface.doSomething(), args: null
realObject doSomething
====== proxy: class com.sun.proxy.$Proxy0, method: public abstract void com.jtchen.proxydemo.BaseInterface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@337f2ee6
ProxyTest
realObject somethingElse: ProxyTest