动态代理

动态代理
方法的作用:在运行时,动态实现一组指定的接口的实现类对象!(在运行时,创建实现了指定的一组接口的对象)

interface A{
}

interface B{
}

Object o=方法(new Class[]{A.class,b.class})
o实现了A和B接口!

动态代理的作用
最终是学习AOP(面向切面编程),它与装饰者模式有点相似,它比装饰者模式更灵活。
这个invoke()方法在什么时候被调用
在调用代理对象所实现接口中的方法时被调用。
Object proxy:当前对象,即代理对象。在调用谁的方法!
Method method:当前被调用的方法(目标方法)
Object[] args:实参

public class AProxy {
@Test
public void fun1() {
/*代理类
*
* 三大参数
* 1.ClassLoader
* 方法需要动态生成一个类,这个类实现了A,B接口,然后创建了这个类的对象!
* 需要生成一个类,这个类也需要加载到方法区中,谁来加载,当然是ClassLoader
*
* 2.Class[] interfaces
* 它是要实现的接口们
*
* 3.InvocationHandler
* 他是调用处理器
*
* 代理对象的实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法
*
* */
ClassLoader loader=this.getClass().getClassLoader();
InvocationHandler h =new InvocationHandler() {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("动态代理");
            return args;
        }

    };
    //使用3大参数创建对象
    Object o =Proxy.newProxyInstance(loader, new Class[] {A.class,B.class}, h);
    //强转成A和B类型,成功了
    A a =(A)o;
    B b=(B)o;
    a.a();
    b.b();
    //o.toString();
    //o.equals(null);
    //o.getClass();//这个不会执行invoke()方法
    String  cc=a.bb("hello");
    System.out.println(cc);

}

}

interface A{
public void a();
public String bb(String a);
}

interface B{
public void b();
}

上述为简单的代理

public class Demo2 {
@Test
public void fun1() {
Waiter manWaiter=new ManWaiter();
ClassLoader loader=this.getClass().getClassLoader();
Class[] interfaces= {Waiter.class};
InvocationHandler h =new WaiterInvocationHandler(manWaiter);
//得到代理对象,代理对象就是在目标对象增强的对象
Waiter waiterProxy=(Waiter)Proxy.newProxyInstance(loader, interfaces, h);
waiterProxy.serve();
}
}

class WaiterInvocationHandler implements InvocationHandler{

private Waiter waiter;


public WaiterInvocationHandler(Waiter waiter) {
    this.waiter=waiter;
    // TODO Auto-generated constructor stub
}


@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("你好!");
    this.waiter.serve();
    System.out.println("再见!");
    return null;
}

}

public interface Waiter {
public void serve();
}

public class ManWaiter implements Waiter{

@Override
public void serve() {
    System.out.println("服务中。。。");
}

}

以上为第二种

public interface Waiter {
public void serve();
}

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*
* 它用来生成代理对象
* 它需要所有的参数
* 目标对象
* 增强
* */

/**
* 1.创建代理工厂 2.给工厂设置三样东西: 目标对象:setTargetObject(XXX);
* 前置增强:setBeforeAdvice(该接口的实现); 后置增强:setAfterAdvice(该接口的实现); 3.调用createProxy()
* 得到代理对象 执行代理对象的目标方法 执行BeforeAdvice的after() 目标对象的目标方法 执行AfterAdvice的after()
*/
public class ProxyFactory {
private Object targetObject;// 目标对象
private BeforeAdvice beforeAdvice;// 前置增强
private AfterAdvice afterAdvice;// 后置增强

/*
 * 用来生成代理对象
 */
public Object createProxy() {
    ClassLoader loader = this.getClass().getClassLoader();
    Class[] interfaces = targetObject.getClass().getInterfaces();
    InvocationHandler h = new InvocationHandler() {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // TODO Auto-generated method stub
            if (beforeAdvice != null) {
                beforeAdvice.before();
            }
            Object result = method.invoke(targetObject, args);// 调用目标对象的目标方法
            if (afterAdvice != null) {
                afterAdvice.after();
            }
            return result;
        }
    };
    Object proxyObject=Proxy.newProxyInstance(loader, interfaces, h);
    return  proxyObject;
}

public Object getTargetObject() {
    return targetObject;
}

public void setTargetObject(Object targetObject) {
    this.targetObject = targetObject;
}

public BeforeAdvice getBeforeAdvice() {
    return beforeAdvice;
}

public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
    this.beforeAdvice = beforeAdvice;
}

public AfterAdvice getAfterAdvice() {
    return afterAdvice;
}

public void setAfterAdvice(AfterAdvice afterAdvice) {
    this.afterAdvice = afterAdvice;
}

}

public class ManWaiter implements Waiter{

@Override
public void serve() {
    System.out.println("服务中。。。");
}

}

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import org.junit.Test;

public class Demo2 {
@Test
public void fun1() {
ProxyFactory factory=new ProxyFactory();//创建工厂
factory.setTargetObject(new ManWaiter());//设置目标对象
factory.setBeforeAdvice(new BeforeAdvice() {//设置前置增强
public void before() {
System.out.println(“您好:”);
}
});

    factory.setAfterAdvice(new AfterAdvice() {//设置后置增强
        public void after() {
            System.out.println("再见!haha ");
        }
    });
    Waiter waiter=(Waiter)factory.createProxy();
    waiter.serve();
}

}

class WaiterInvocationHandler implements InvocationHandler{

private Waiter waiter;


public WaiterInvocationHandler(Waiter waiter) {
    this.waiter=waiter;
    // TODO Auto-generated constructor stub
}


@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("你好!");
    this.waiter.serve();
    System.out.println("再见!");
    return null;
}

}

public class BeforeAdvice {

public void before() {
    // TODO Auto-generated method stub

}

}

public class AfterAdvice {

public void after() {
    // TODO Auto-generated method stub

}

}

//第二种就是代理模式的简单应用,
而第三种则是创建了一个工厂模式,利用这个工厂类,可以组装出各种格式的代理类

代理类的重点:
代理类的第一个重点就是InvocationHandler
InvocationHandler :其实就是利用在这个类中执行,在目标方法的前后添加一些业务逻辑。这就是代理模式。
第二个重点就是:
Proxy.newProxyInstance(loader, interfaces, h);
这个类的三个参数是最重要的方法。利用这个方法,可以实例化该类。
总的来说,代理模式,其实就是将前置增强和后置增强与目标方法装配起来。让这个类能够做更多的事。有利于拓展。
弄懂了这个,其实就是为了更好的学习AOP。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值