反射是动态语言的关键,动态代理正是通过反射实现
一.静态代理:
静态代理是通过构建代理类对象,将被代理类对象以参数的形式传递给代理类对象,进而在代理类对象中调用被代理类的方法。
代码实现如下:
1.创建接口
2.定义被代理类实现接口
3.定义代理类,通过代理类的构造方法为其被代理类对象属性赋值,代理类的productCloth()方法实际调用的是被代理类对象的方法
4.建立main方法测试
package D19;
/**
* @Author: wj
* @Date: 2018/12/1 16:19
* @Version 1.0
*
* 静态代理演示
* 使用一个代理类将对象包装起来,然后用该代理对象取代原始对象,任何对原始对象的调用
* 都要通过代理,代理对象决定是否以及何时将方法调用转到原始对象上
*/
/**
*接口
*/
interface ClothFactory{
public void productCloth();
}
/**
*被代理类
*/
class NikeClothFactory implements ClothFactory{
public void productCloth() {
System.out.println("NIKE");
}
}
/**
* 代理类
*/
class ProxyFactory implements ClothFactory{
ClothFactory cf ;
/**创建代理类对象时,实际传入的是被代理类对象
* @param cf(多态)
*/
public ProxyFactory(ClothFactory cf){
this.cf=cf;
}
public void productCloth() {
cf.productCloth();
}
}
public class TestStaticAgent {
public static void main(String[] args) {
NikeClothFactory nikeClothFactory = new NikeClothFactory(); //创建被代理类对象
//代理类对象
ProxyFactory proxyFactory = new ProxyFactory(nikeClothFactory); //创建代理类对象
//虽然执行的是代理类的productCloth();但实际调用的是被代理类的productCloth()方法
proxyFactory.productCloth();
}
}
5.输出:
二.动态代理
动态代理比静态代理更加自如,不必考虑代理类接受对象的类型,具有更加自如地灵活性,实现了动态代码
步骤与静态代理相同
1.定义接口
2.定义实现接口的被代理类
3.定义实现了InvocationHandler接口的代理类,定义blind方法接受被代理类对象(作用有两个1.为属性赋值,2返回实现了被代理类所实现接口的代理类对象),实现了invoke方法,该方法实际就是被带了类的方法
代码如下:
package D19;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @Author: wj
* @Date: 2018/12/2 13:38
* @Version 1.0
*
* 动态代理的使用
*/
//接口
interface Subject{
void action();
}
/**
* 被代理类
*/
class RealSubject implements Subject{
public void action() {
System.out.println("被代理类执行");
}
}
/**
* 代理类
*/
class MyInvocationHandler implements InvocationHandler{
Object object;//实现了接口的被代理类对象的声明(RealSubject)
// 1.给被代理类的对象实例话
//2.返回一个代理类的对象
public Object blind(Object obj){
this.object = obj;
//三个参数被代理类对象的classLoader,被代理类实现的接口,实现了InvocationHandler接口的类对象
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
//当通过代理类的对象发起对被代理类方法的调用时,都会转为对invoke方法的调用,进而实现动态效果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//returnVal是被代理类方法的返回值
Object returnVal = method.invoke(object,args);
System.out.println("invoke方法被调用");
return returnVal;
}
}
public class TestDynamicAgent {
public static void main(String[] args) {
//1.构造被代理类的对象
RealSubject realSubject = new RealSubject();
//2创建一个实现了InvocationHandle接口的对象
MyInvocationHandler myInvocationHandler = new MyInvocationHandler();
//3.通过myInvocationHandle的blind方法 ,返回实现了被代理类所实现的接口的代理类对象
Object obj = myInvocationHandler.blind(realSubject);
Subject sub = (Subject) obj;//sub就是i代理类的对象
sub.action();//转到对代理类的inovke方法的调用
// //测试动态代理
// NikeClothFactory clothFactory = new NikeClothFactory();
// Object demo = myInvocationHandler.blind(clothFactory);
// ClothFactory clo = (ClothFactory) demo;
// clo.productCloth();
}
}
输出:
在main方法中还写了一个测试,具体的应用了动态代理。