好久没有动笔了,最近想巩固一下自己的基础知识,最近听到一同事问为什么JDK动态代理不能代理类,一听感觉懵逼呀!自己好像也不能很好的描述出来,所以想用2篇文章来复习一下动态代理知识;

一、什么是静态代理?什么是动态代理?  

  静态代理:
    静态代理是在写代码中就把各个代理关系给理清了,在编译期就确定了类之间的关系;
  动态代理:
    在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能;

二、为什么要使用代理?  

  兄弟,你打方法的出入参的代码可以推一个房子了吧。使用代理可以将代码解耦,很多时候我们只要去关注我们最核心的实现,一些其他方面我可以交给代理去实现。最好的说明就是我们日常的AOP日志了,就是靠代理实现的。

三、简单的代理实现  

  静态代理的简单实现代码参考我前面的代理模式的代码:
  今天我们先要写一下动态代理的简单代码:  

   InvocationHandler    

    InvocationHandler是JDK中提供的专门用于实现基于接口的动态代理的接口,主要用于进行方法调用模块,而代理类和实例的生成需要借助Proxy类完成。每个代理类的实例的调用处理器都是实现该接口实现的,而且是必备的,即每个动态代理实例的实现都必须拥有实现该接口的调用处理器,也可以这么说,每个动态代理实例都对应一个调用处理器。这里要区分两个概念,代理类和代理实例,调用处理器是在创建代理实例的时候才与其关联起来的,所以它与代理实例是一一对应的,而不是代理类。   

  Proxy    

    Proxy类是JDK提供的用于生成动态代理类和其实例的类。我们可以通过Proxy中的静态方法getProxyClass来生成代理类,需要的参数为类加载器和接口列表(数组),然后再通过反射调用代理类的构造器来生成代理实例,需要以一个InvocationHandler作为参数(体现出方法调用是与实例相关的,而非类)。
  了解了上面我们开始写代码实现:

  先写一个接口UserService,里面包含一个根据id查询用户名的方法,我们在这个查询方法的前后打印出出入参

 1 package com.roc.study.proxy;
2
3 /**
4 * <code>用户service</code>
5 * <b>Note</b>
6 *
7 * @author liaowp
8 * @see
9 * @since 2018/5/14
10 */
11
12 public interface UserService {
13
14 /**
15 * 查询用户名称
16 * @param id
17 * @return
18 */
19 String getUserName(Integer id);
20
21 }
 1 package com.roc.study.proxy;
2
3 /**
4 * <code>用户service实现类</code>
5 * <b>Note</b>
6 *
7 * @author liaowp
8 * @see
9 * @since 2018/5/14
10 */
11 public class UserServiceImpl implements UserService {
12
13 /**
14 * 查询用户名称
15 *
16 * @return
17 */
18 @Override
19 public String getUserName(Integer id) {
20 System.out.println("liaowp");
21 return "liaowp";
22 }
23 }
 1 package com.roc.study.proxy;
2
3 import java.lang.reflect.InvocationHandler;
4 import java.lang.reflect.Method;
5 import java.lang.reflect.Proxy;
6
7 /**
8 * <code>用户代理类</code>
9 * <b>Note</b>
10 *
11 * @author liaowp
12 * @see
13 * @since 2018/5/14
14 */
15
16 public class UserInvocationHandler implements InvocationHandler {
17
18 private Object target;
19
20 public UserInvocationHandler(Object target) {
21 this.target = target;
22 }
23
24 /**
25 * 在代理实例上处理方法调用并返回结果。
26 * 当在与其关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
27 * @param proxy 我们所代理的那个真实对象
28 * @param method 方法
29 * @param args 入参
30 * @return
31 * @throws Throwable
32 */
33 @Override
34 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
35 System.out.println("入参args->" + args);
36 // 执行目标对象的方法
37 Object result = method.invoke(target, args);
38 System.out.println("出参args->"+result.toString());
39 return result;
40 }
41
42 /**
43 * 获取目标对象的代理对象
44 * @return 代理对象
45 */
46 public Object getProxy() {
47 return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
48 target.getClass().getInterfaces(), this);
49 }
50
51 }
package com.roc.study.proxy;

/**
* <code>代理测试类</code>
* <b>Note</b>
*
* @author liaowp
* @see
* @since 2018/5/14
*/
public class ProxyTest { public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserInvocationHandler userInvocationHandler = new UserInvocationHandler(userService);
// 根据目标对象生成代理对象
UserService proxy = (UserService) userInvocationHandler.getProxy();
// 调用代理对象的方法
proxy.getUserName(1);
}
}

运行结果:

入参args->[Ljava.lang.Object;@5cad8086
liaowp
出参args->liaowp

Process finished with exit code 0

Java动态代理(一)的更多相关文章

  1. Java 动态代理机制详解

    在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的 ...

  2. Java动态代理全面分析

    代理模式 解说:给某一个对象提供一个代理,并由代理对象控制对原对象的引用: 代理模式需要以下几个角色: 1  主题:规定代理类和真实对象共同对外暴露的接口: 2  代理类:专门代理真实对象的类: 3 ...

  3. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  4. Java 动态代理作用是什么?

    Java 动态代理作用是什么?   1 条评论 分享   默认排序按时间排序 19 个回答 133赞同反对,不会显示你的姓名 Intopass 程序员,近期沉迷于动漫ING 133 人赞同 ① 首先你 ...

  5. java动态代理原理

    我们经常会用到Java的动态代理技术, 虽然会使用, 但是自己对其中的原理却不是很了解.比如代理对象是如何产生的, InvocationHandler的invoke方法是如何调用的?今天就来深究下Ja ...

  6. java 动态代理示例,带主要注释

    Java proxy是基于反射,仅仅支持基于接口的动态代理. java 动态代理是一切架构的基础,必须了解. 废话少说,先上代码获得感性认识. 示例代码有主要注释. 接口: public interf ...

  7. java动态代理浅析

    最近在公司看到了mybatis与spring整合中MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 于是想起了java的动态代理,然后就有了这篇文章 ...

  8. Java 动态代理

    被代理的接口特点: 1. 不能有重复的接口,以避免动态代理类代码生成时的编译错误. 2. 这些接口对于类装载器必须可见,否则类装载器将无法链接它们,将会导致类定义失败. 3. 需被代理的所有非 pub ...

  9. [转]java动态代理(JDK和cglib)

    转自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理 ...

  10. java动态代理模式

    java动态代理机制详解 Spring的核心AOP的原理就是java的动态代理机制. 在java的动态代理机制中,有两个重要的类或接口: 1.InvocationHandler(Interface): ...

随机推荐

  1. 三层登录实例VB.NET版详解---理论加实战篇

    层,百度百科这样解释,首先-重叠起来的东西:重叠起来的东西中的一部分:层次|表层|大气层.其次-重叠:重复:层峦叠嶂|层出不穷.最后-量词,用于可以分出层次的事物,女孩儿强烈的第六感,三层中的层一定是 ...

  2. 被final关键字坑了

    一直都傻傻的以为用final关键字定义的都是不可变的.没想到的是对基本类型来说,这是一直成立的. 但是对于final修饰的对象,仍然可以修改对象里面的对象和成员变量.不变的只是当前对象的地址. 昨天我 ...

  3. Java集合之TreeSet

    TreeSet是一个有序的集合,它的作用是提供有序的Set集合.它继承了AbstractSet抽象类,实现了NavigableSet<E>,Cloneable,Serializable接口 ...

  4. 排序算法(二)Sort with Swap(0,*)

    对于一个由0到N-1的序列,如果只能交换0和另一个数的位置,求多少次能够将序列变为递增序列. 输入为<N> <序列>(N和序列之间有一个空格,序列元素之间均有一个空格). 设序 ...

  5. 滑动UITableViewCell出现多个按钮

    iOS > = 5.0使用第三方效果图 iOS> = 8.0使用系统方法效果图 MGSwipeTableCell(Github上的三方库)- iOS >= 5.0 直接使用比较简单 ...

  6. 套接字编程相关函数(1:套接字地址结构、字节序转换、IP地址转换)

    1. 套接字地址结构 1.1 IPv4套接字地址结构 IPv4套接字地址结构通常也称为“网际套接字地址结构”,它以sockaddr_in命名,定义在<netinet/in.h>头文件中.下 ...

  7. 写一个dup2功能相同的函数,不能调用 fcntl 函数,并且要有出错处理

    实现的时候用到系统原来的dup函数 // mydup2.c // 2015/08/17 Lucifer Zhang version1.0 // write my own dup2 function / ...

  8. linux内核自旋锁API

    我们大概都了解,锁这种机制其实是为了保护临界区代码的,关于使用和定义,我总结的API如下: #include <linux/spinlock.h> 定义自旋锁 spinlock_t loc ...

  9. Mina源码阅读笔记(六)—Mina异步IO的实现IoFuture

    IoFuture是和IoSession紧密相连的一个类,在官网上并没有对它的描述,因为它一般不会显示的拿出来用,权当是一个工具类被session所使用.当然在作用上,这个系列可并不简单,我们先看源码的 ...

  10. obj-c编程17:键值观察(KVO)

    说完了前面一篇KVC,不能不说说它的应用KVO(Key-Value Observing)喽.KVO类似于ruby里的hook功能,就是当一个对象属性发生变化时,观察者可以跟踪变化,进而观察或是修正这个 ...