java动态代理笔记

本文介绍了Java中的静态代理和动态代理概念,通过代码示例展示了静态代理的实现方式,以及动态代理如何通过Proxy类和InvocationHandler接口简化代理类的创建。动态代理在AOP(面向切面编程)中的应用被提及,指出动态代理的invoke方法可以实现类似AOP的逻辑,如在方法调用前后插入额外操作。
摘要由CSDN通过智能技术生成

我其实觉得反射的内容不太重要,也不是不太重要,但是动态代理才是重中之重,之后学spring原理的时候要用到,AOP面向切面编程的原理,就是动态代理,所以回来补课了

代理模式:使用代理将对象包装起来,用该代理对象取代原始对象
在这里插入图片描述
首先是一个静态代理的例子

import org.junit.Test;

interface ClothFactory{
    void productCloth();
}
//代理类
class ProxyClothFactory implements ClothFactory{

    private ClothFactory factory;

    ProxyClothFactory(ClothFactory factory){
        this.factory = factory;
    }

    public void productCloth() {
        System.out.println("代理工厂开始做事情");
        factory.productCloth();
        System.out.println("代理工厂结束做事情");
    }
}
//被代理类
class NikeClothFactory implements ClothFactory{
    public void productCloth() {
        System.out.println("nike生产衣服");
    }
}

public class StaticProxyTest {

    @Test
    public void test(){
        //创建被代理类对象
        ClothFactory nike = new NikeClothFactory();

        //创建代理类对象
        ClothFactory proxyClothFactory = new ProxyClothFactory(nike);
        
        proxyClothFactory.productCloth();
    }

}

最后运行时的结果如下,可以看到代理方法和原对象的方法全部都调用的
在这里插入图片描述

在静态代理中,可以看到,所有的类都在编译时确定好了,那么假如nike还需要代理鞋生产,代理裤子生产,那么你还需要写ProxyShoesFactory,ProxyPantsFactory,这样会导致代理类变得非常多,代码变得臃肿

动态代理

那么接下来写一个动态代理的例子,可以看到在这里面,实现了一个动态代理工厂ProxyFactory
调用getProxyInstance就可以拿到动态代理对象,在这里我并没有创建ProxyClothFactory,
ProxyHumanFactory等静态代理所需要的类,而是一个动态代理类全部搞定,一个类,不论是什么对象要创建代理对象都可以用这个搞定。

import org.junit.Test;

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

interface Human{

    String getBelief();
    void eat(String food);

}
//被代理类
class SuperMan implements Human{

    public String getBelief() {
        return "god";
    }

    public void eat(String food) {
        System.out.println("我吃了"+food);
    }
}
/*
动态代理需要解决的问题:
1.如何根据内存中的被代理类,动态的创建一个被代理类及其对象
2.通过代理类对象调用方法时,如何去动态调用同名的方法
 */

class ProxyFactory{

    //调用该方法,返回代理类对象
    public static Object getProxyInstance(Object obj){
        //该函数三个变量为,类加载器,该类实现的接口,以及一个Handler,
        ClassLoader classLoader = obj.getClass().getClassLoader();
        Class<?>[] interfaces = obj.getClass().getInterfaces();

        MyInvocationHandler handler = new MyInvocationHandler(obj);

        Object newProxyInstance = Proxy.newProxyInstance(
                classLoader, interfaces, handler);

        return newProxyInstance;

    }
}
//实现一个Handler类
class MyInvocationHandler implements InvocationHandler{
    private Object obj;

    public MyInvocationHandler(Object obj){
        this.obj=obj;
    }


    //当我们通过代理类的对象,调用他们的方法的时候,就会通过invoke去调用
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理开始");
        Object invoke = method.invoke(obj, args);
        System.out.println("动态代理结束");
        return invoke;
    }
}


public class ProxyTest {

    @Test
    public void ProxyTest(){
        Human human = new SuperMan();
        //proxyInstance就是代理对象
        Human proxyInstance = (Human) ProxyFactory.getProxyInstance(human);

        String belief = proxyInstance.getBelief();
        System.out.println(belief);
        proxyInstance.eat("面条");

        System.out.println("********************");

        ClothFactory nikeClothFactory =  new NikeClothFactory();
        ClothFactory nikeProxyInstance = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);

        nikeProxyInstance.productCloth();

    }
}

把自己实现的invoke方法中的method.invoke用try catch finally包围起来,然后在四个不同的地方插入代码块,不就是AOP的原理吗

	try{
		//before
		method.invoke();
		//afterReturning
	}catch(Exception e){
		//afterThrowing
	}finally{
		//after
	}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值