动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。
动态代理使用场合: 调试、 远程方法调用
代理设计模式的原理:使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上
1静态代理
package reflections;
//静态代理模式
//接口
interface ClothFactory{
void productCloth();
}
//被代理类
class NikeClothFactory implements ClothFactory{
@Override
public void productCloth() {
System.out.println("NIKE 工厂生产一批衣服");
}
}
//代理类
class ProxyFactory implements ClothFactory{
ClothFactory cf;
public ProxyFactory(ClothFactory cf) {
this.cf = cf;
}
@Override
public void productCloth() {
System.out.println("代理类开始执行,收代理费");
this.cf.productCloth();
}
}
public class TestCloseProduct {
public static void main(String[] args) {
//代理类实际执行的是被代理类的方法
ProxyFactory proxyf = new ProxyFactory(new NikeClothFactory());
proxyf.productCloth();
}
}
package reflections;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理的使用:不需要提前知道被代理类及其实现的接口
//接口
interface Subject{
void action();
}
//被代理类
class RealSubject implements Subject{
@Override
public void action() {
System.out.println("我是被代理类,要被执行的。");
}
}
class MyInvocationHandler implements InvocationHandler{
Object obj; //实现了接口的被代理类的对象声明
//给被代理类的对象实例化,返回一个代理类对象
public Object blind(Object obj){
this.obj = obj;
//返回一个代理类对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
//当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object retVal = method.invoke(obj, args);
return retVal;
}
}
public class TestDynamicProxy {
public static void main(String[] args) {
//创建被代理类的对象
RealSubject real = new RealSubject();
//创建一个实现InvocationHandler接口的对象
MyInvocationHandler handler = new MyInvocationHandler();
//调用blind()方法返回一个同样实现了 real所在类实现的接口Subject 的代理类的对象
Object obj = handler.blind(real);
Subject sub = (Subject) obj;
sub.action(); //转到对InvocationHandler的invoke()方法的调用
//另一个例子
NikeClothFactory nike = new NikeClothFactory();
ClothFactory cf = (ClothFactory) handler.blind(nike);
cf.productCloth();
}
}
3 动态代理与AOP(Aspect Orient Programming)
package reflections;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//接口
interface Human{
void info();
void fly();
}
//被代理类
class SuperMan implements Human{
@Override
public void info() {
System.out.println("我是超人!");
}
@Override
public void fly() {
System.out.println("I think I can fly!");
}
}
class HumanUtil{
public void method1(){
System.out.println("=============方法1================");
}
public void method2(){
System.out.println("=============方法1================");
}
}
class MInvocationHandler implements InvocationHandler{
Object obj; //被代理对象声明
public void setObject(Object obj){
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HumanUtil h = new HumanUtil();
h.method1();
Object retVal = method.invoke(obj, args);
h.method2();
return retVal;
}
}
class MyProxy{
//动态创建一个代理类的对象
public static Object getProxyInstcance(Object obj){
MInvocationHandler handler = new MInvocationHandler();
handler.setObject(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
}
}
public class TestAOP {
public static void main(String[] args) {
SuperMan sp = new SuperMan(); //创建一个被代理类对象
Object obj=MyProxy.getProxyInstcance(sp);
Human hu = (Human) obj;
hu.info();
System.out.println();
hu.fly();
}
}