代理模式之JDK动态代理

JDK动态代理

上一篇博文静态代理介绍了静态代理的简单实现,以及静态代理的缺点:

  1. 代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
  2. 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。

JDK动态代理的优点

  1. 代理对象不需要实现接口,这样就不会有众多的代理类;
  2. 利用JDK生成代理对象,动态地在内存中构建代理对象,即在程序运行时,通过反射机制动态生成;
  3. 不需要事先知道要代理的是什么,只有在运行时才确认;

JDK动态代理缺点

  1. 目标类必须实现的某个接口,如果某个类没有实现接口则不能生成代理对象;
  2. 只能代理接口,要代理类需要使用第三方的CLIGB等类库;

JDK动态代理实例演示

  • 创建接口:Animal
public interface Animal {
    void printName();
}
  • 创建目标对象Dog并实现接口Animal
@Component
public class Dog implements Animal {
    @Override
    public void printName() {
        System.out.println("===== I am a dog ====");
    }
}
  • 创建代理代理类JDKProxy获取代理对象
@Component
public class JDKDogProxy {
    @Autowired
    private Dog dog; // 创建目标对象

    public Animal getJDKProxy() {
   		 // 参数一:ClassLoader loader,指定使用哪个类装载器生成代理对象,一般用代理类的类加载器;
        // 参数二:Class<?>[] interfaces,通过指定接口来指定哪个对象的代理对象,即指定代理类实现的接口;
        // 参数三:InvocationHandler h,通过实现handler的invoke方法来指定要在代理对象的方法里做什么事;
        return (Animal) Proxy.newProxyInstance(Dog.class.getClassLoader(), Dog.class.getInterfaces(), (Object proxy, Method method, Object[] args) -> {
            if (method.getName().equals("printName")) {
                System.out.println("++++ 调用目标方法前处理 ++++");
                method.invoke(dog, args);
                System.out.println("++++ 调用目标方法后处理 ++++");
            }

            return null;
        });
    }
}
  • 测试动态代理
@SpringBootTest
@RunWith(SpringRunner.class)
public class ProxyTest {
    @Autowired
    private JDKDogProxy jdkDogProxy;

    @Test
    public void testJDKProxy() {
        Animal dog = jdkDogProxy.getJDKProxy();
        dog.printName();
    }
}
  • 运行结果
    在这里插入图片描述

GitHub源码地址JDK动态代理


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值