JDK动态代理[1]----代理模式实现方式的概要介绍

日常工作中经常会接触到代理模式,但一直没有对其进行深究。代理模式一直就像一团迷雾一样存在我心里,什么是代理模式?为什么要使用代理?代理模式有哪些实现?它的底层机制是怎样的?这些问题促使着我迫切想要揭开代理模式的神秘面纱。

1. 什么是代理模式?

日常生活中我们经常会碰到代理模式,例如我们找房产中介帮我们介绍房子,找婚姻中介帮我们介绍对象,找保洁帮我们打理房间,找律师帮我们进行诉讼等。我们在无形中运用到了代理模式,却不知道它的存在。

2. 为什么要使用代理?

运用代理可以使我们的生活更加便利,有了代理,我们不需要自己去找房子,不需要自己去找对象,不需要自己去打理房间,不需要自己去诉讼。当然,你也可以选择一切都自己来干,但是存在前提条件,一是你是否都具备这样的资源和能力来做这些事情,二是你是否愿意花费这么多精力和时间来做这些事情。总之,代理模式使我们各专其事,我们可以将时间浪费在美好的事情上,而不用天天被一些琐事所羁绊。

3. 代理模式有哪些实现?

Java中的代理有静态代理和动态代理,下面我会分别用一个简单的例子来介绍一下静态代理和动态代理代码实现。

3.1 静态代理

代理接口:UserDao.java

1 public interface UserDao {
2
3     void save();
4
5 }

目标对象:UserDaoImpl.java

1 public class UserDaoImpl implements UserDao {
2
3     @Override
4     public void save() {
5         System.out.println("正在保存用户...");
6     }
7
8 }

代理对象:TransactionHandler.java

 1 public class TransactionHandler implements UserDao {
 2
 3     //目标代理对象
 4     private UserDaoImpl target;
 5
 6     //构造代理对象时传入目标对象
 7     public TransactionHandler(UserDaoImpl target) {
 8         this.target = target;
 9     }
10
11     @Override
12     public void save() {
13         //调用目标方法前的处理
14         System.out.println("开启事务控制...");
15         //调用目标对象的方法
16         target.save();
17         //调用目标方法后的处理
18         System.out.println("关闭事务控制...");
19     }
20
21 }

测试类:Main.java

 1 public class Main {
 2
 3     public static void main(String[] args) {
 4
 5         //新建目标对象
 6         UserDaoImpl target = new UserDaoImpl();
 7
 8         //创建代理对象, 并使用接口对其进行引用
 9         UserDao userDao = new TransactionHandler(target);
10
11         //针对接口进行调用
12         userDao.save();
13
14     }
15
16 }

测试结果:

总结:

总的来说静态代理实现简单也容易理解,但是静态代理不能使一个代理类反复作用于多个目标对象,代理对象直接持有目标对象的引用,这导致代理对象和目标对象类型紧密耦合了在一起。如果UserDao接口下还有另一个实现类也需要进行事务控制,那么就要重新写一个代理类,这样就会产生许多重复的模版代码,不能达到代码复用的目的。而动态代理就可以很好的解决这样的问题。

3.2 动态代理

代理接口:UserDao.java

1 public interface UserDao {
2
3     void save();
4
5 }

目标对象:UserDaoImpl.java

1 public class UserDaoImpl implements UserDao {
2
3     @Override
4     public void save() {
5         System.out.println("保存用户信息...");
6     }
7
8 }

代理对象:TransactionHandler.java

 1 public class TransactionHandler implements InvocationHandler {
 2
 3     //需要代理的目标对象
 4     //这里设计为可以为任意对象添加事务控制, 所以将目标对象声明为Object
 5     private Object target;
 6
 7     //构造TransactionHandler时传入目标对象
 8     public TransactionHandler(Object target) {
 9         this.target = target;
10     }
11
12     @Override
13     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
14         //调用目标方法前的处理
15         System.out.println("开启事务控制...");
16         //调用目标对象的方法
17         Object result = method.invoke(target, args);
18         //调用目标方法后的处理
19         System.out.println("关闭事务控制...");
20         //放回方法调用结果
21         return result;
22     }
23
24 }

测试类:Main.java

 1 public class Main {
 2
 3     public static void main(String[] args) {
 4
 5         //新建目标对象
 6         Object target = new UserDaoImpl();
 7
 8         //创建事务处理器
 9         TransactionHandler handler = new TransactionHandler(target);
10
11         //生成代理类并使用接口对其进行引用
12         UserDao userDao = (UserDao)Proxy.newProxyInstance(target.getClass().getClassLoader(),
13                                                           target.getClass().getInterfaces(),
14                                                           handler);
15         //针对接口进行方法调用
16         userDao.save();
17
18     }
19
20 }

测试结果:

总结:

之前我们发现了静态代理会产生许多重复代码,不能很好的进行代码复用,而动态代理能够很好的解决这个问题,代理类TransactionHandler实现了InvocationHandler接口,并且它持有的目标对象类型是Object,因此事务控制代理类TransactionHandler能够代理任意的对象,为任意的对象添加事务控制的逻辑。因此动态代理才真正的将代码中横向切面的逻辑剥离了出来,起到代码复用的目的。但是动态代理也有缺点,一是它的实现比静态代理更加复杂也不好理解;二是它存在一定的限制,例如它要求需要代理的对象必须实现了某个接口;三是它不够灵活,动态代理会为接口中的声明的所有方法添加上相同的代理逻辑。当然,这只是JDK动态代理所存在的一些缺陷,动态代理还有另外的实现如使用CGLIB库,在本文不做介绍,读者可以自行去了解。

全文总结:

本文从概念上为大家介绍了什么是代理模式,为什么要使用代理以及代理模式有哪些实现,并使用简单的例子为大家介绍静态代理和JDK动态代理的实现,分析了静态代理和动态代理各自的优缺点,使大家对代理模式有了一些大致的了解。不过到这里相信读者对于JDK动态代理还是会感到困惑,想要进一步了解代理类是怎样产生的。后续章节笔者会深入源码为大家呈现整个代理类的产生过程。

原文地址:https://www.cnblogs.com/liuyun1995/p/8144628.html

时间: 2024-07-29 04:33:20

JDK动态代理[1]----代理模式实现方式的概要介绍的相关文章

JDK动态代理[2]----JDK动态代理的底层实现之Proxy源码分析

在上一篇里为大家简单介绍了什么是代理模式?为什么要使用代理模式?并用例子演示了一下静态代理和动态代理的实现,分析了静态代理和动态代理各自的优缺点.在这一篇中笔者打算深入源码为大家剖析JDK动态代理实现的机制,建议读者阅读本篇前可先阅读一下笔者上一篇关于代理模式的介绍<JDK动态代理[1]----代理模式实现方式的概要介绍> 上一篇动态代理的测试类中使用了Proxy类的静态方法newProxyInstance方法去生成一个代理类,这个静态方法接收三个参数,分别是目标类的类加载器,目标类实现的接口

动态代理及其两种实现方式(JDK、CGLIB)

什么是代理模式 为某对象提供一个代理,从而通过代理来访问这个对象. 代理模式的角色组成 代理模式有三种角色组成: 抽象角色:通过接口或抽象类声明真实角色实现的业务方法. 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作. 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用. 我的总结: 抽象角色就是一个接口或抽象类,定义一些方法: 真实角色就是对抽象角色以及其中的方法进行实现: 代理角色也要实现抽象角色,并且注入真实角色

模式的秘密-代理模式(2)-JDK动态代理

代理模式-动态代理 (1) (2) 代码实践动态代理: 第一步:被代理类的接口: package com.JdkProxy; public interface Moveable { void move(); } 第二步:被代理类: package com.JdkProxy; import java.util.Random; public class Car implements Moveable { @Override public void move() { //实现开车 try { Thre

zbb20180930 代理模式 -静态代理-jdk动态代理-cglib动态代理

CGLIB与JDK动态代理区别 区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理.而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理. 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2.如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3.如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB

Spring AOP --JDK动态代理方式

我们知道Spring是通过JDK或者CGLib实现动态代理的,今天我们讨论一下JDK实现动态代理的原理. 一.简述 Spring在解析Bean的定义之后会将Bean的定义生成一个BeanDefinition对象并且由BeanDefinitionHolder对象持有.在这个过程中,如果Bean需要被通知切入,BeanDefinition会被重新转换成一个proxyDefinition(其实也是一个BeanDefinition对象,只不过描述的是一个ProxyFactoryBean).ProxyFa

动态代理模式——JDK动态代理

今天,我就来讲一下动态代理的设计模式. 动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.操作动态代理需要两个步骤:一.代理对象和真实对象建立代理关系.二.实现代理对象的代理逻辑方法. 在Java中,有很多的动态代理技术.如:JDK.CGLIB.Javassist.ASM,其中最常用的动态代理技术有两种:一种是JDK动态代理,这是JDK自带的功能:另一种就是CGLIB,这是第三方提供的一种技术. 这次主要讲的是JDK动态代理和CGLIB动态代理.在JDK动态代理中,我们

Spring声明式事务的实现方式选择(JDK动态代理与cglib)

1.简介 Spring声明式事务的具体实现方式是动态决定的,与具体配置.以及事务代理对象是否实现接口等有关. 2.使用JDK动态代理的情况 在满足下面两个条件时,Spring会选择JDK动态代理作为声明式事务的实现方式. (1)事务代理类必须实现接口且不能显式继承父类(Object这个父类不算). (2)配置:springboot的启动类要加上@EnableTransactionManagement和@EnableAspectAutoProxy注解,且其中的proxyTargetClass属性要

Java进阶之 JDK动态代理与Cglib动态代理

一.动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式[Proxy Pattern]), 动态代理类的字节码是在程序运行时由Java反射机制动态生成. 注意: 1.AspectJ是采用编译时生成AOP代理类,具有更好的性能,但是需要使用特定的编译器进行处理 2.Spring AOP采用运行时生成AOP代理类,无需使用特定编译器进行处理,但是性能相对于AspectJ较差 二.JDK动态代理 [对有实现接口的对象做代理] 1.JDK动态代理中 需要了解的

【转载】Java JDK 动态代理(AOP)使用及实现原理分析

转自:http://blog.csdn.net/jiankunking/article/details/52143504 版权声明:作者:jiankunking 出处:http://blog.csdn.net/jiankunking 本文版权归作者和CSDN共有 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持