一、反射

反射在之前的文章中详细的解释过了,简单概括就是:可以动态的获取到一个类内部的所有的信息,动态的去创建对象和使用对象以及可以操作对象的属性和方法。

二、代理

首先解释一下代理:使用一个代理对象将对象包装起来,然后用该代理对象来取代该对象,任何对原始对象的调用都要通过代理,代理对象决定是否以及何时调用原始对象的方法。

三、静态代理

静态代理:被代理对象和代理对象要实现同一套接口且代理对象内部要包含被代理对象,被代理对象覆盖重写接口方法,在方法内部加上实际业务上的增强。

代码目录

代码演示

//公共接口
public interface ZhangSanInterface {
//定义一个吃饭的抽象方法
void eat();
} //张三类
public class ZhangSan implements ZhangSanInterface {
@Override
public void eat() {
System.out.println("吃饭。。。"); //实现方法体
}
} //张三代理类
public class ZhangSanProxy implements ZhangSanInterface{ private ZhangSanInterface zhangSanInterface; public ZhangSanProxy(ZhangSanInterface zhangSanInterface) {
this.zhangSanInterface = zhangSanInterface;
} @Override
public void eat() {
System.out.println("饭前洗手。。"); //方法前增强
zhangSanInterface.eat();
System.out.println("饭后洗碗。。"); //方法后增强
}
} //测试类
public class Main01 {
public static void main(String[] args) {
ZhangSanProxy proxy = new ZhangSanProxy(new ZhangSan()); //代理对象中传入张三对象
proxy.eat();
}
}

总结:静态代理不需要使用反射机制就能够实现,但是也存在了很明显的缺陷,如果想要在加一些其他的被代理类,必须要修改代码,不符合开闭原则(对外扩展开放,对内修改关闭),扩展性差、维护性差。

四、动态代理

动态代理:在程序的执行时(动态),使用jdk的反射机制,创建对象的能力,创建的是代理类的对象,而不用我们自己创建类文件。

1、JDK动态代理

  使用java反射包中的类和接口实现动态代理的功能。 反射包 java.lang.reflect,里面有三个类:InvocationHandler、Method、Proxy 

  1) InvocationHandler接口(调用处理器) :就-一个方法invoke ( )
      invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在invoke ()方法中。
      代理类完成的功能:
    1.调用目标方法,执行目标方法的功能
    2.功能增强,在目标方法调用时,增加功能。

   方法原型:
   参数: object proxy :jdk创建的代理对象,无需赋值。
       Method method: 目标类中的方法,jdk提供me thod对象的
       object[] args: 目 标类中方法的参数,jdk提供的 。
     public object invoke (object proxy, Method method, Object[] args)
     InvocationHandler接口:表示你的代理要千什么。

      怎么用: 1.创建类实现接口Invocati onHandler
           2.重写invoke()方法,把原来静态代理中代理类要完成的功能,写在这。

  2) Method类:表示方法的,确切 的说就是目标类中的方法.
      作用:邇过Method可以执行某个目标类的方法,Method. invoke() ;
      method. invoke(目标对象,方法的参数)

  3) Proxy类: 核心的对象,创建代理对象。之前创建对象都是new类的构造方法(),现在我们是使用Proxy类的方法,代替new的使用。
      方法:静态方法 newProxyInstance ()
      作用是:创建代理对象, 等同于静态代理中的   代理类 proxy = new 代理类() ; 

   参数:
      1. ClassLoader loader 类加载器,负责向内存中加载对象的。使用反射获取对象的ClassLoader类a,a. getCalss () .getClassLoader(),目标对象的类加载器。
      2. Class<?>[] interfaces:接口,目标对象实现的接口,也是反射获取的。
      3. InvocationHandler h :我们自己写的,代理类要完成的功能。

   返回值:newProxyInstance () 的返回值就是代理对象。

  实现动态代理的步骤
    1.创建接口,定义目标类要完成的功能
    2.创建目标类实现接口
    3.创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能
    1.调用目标方法
    2.增强功能
    4.使用Proxy类的静态方法,创建代理对象。并把返回值转为接口类型。

  代码目录

  代码展示

//目标接口
public interface Target {
void eat();
} //目标类
public class TargetImpl implements Target {
@Override
public void eat() {
System.out.println("吃饭饭。。");
}
} //必须实现InvocationHandler接口,完成动态代理要做的功能(1.调用目标方法 2.功能增强)
public class MyHandler implements InvocationHandler { private Object taget; public MyHandler(Object taget) {
this.taget = taget;
} //动态代理:对象是活动的,不是固定的,需要传进来
//传入是谁,就给谁创建代理。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("洗手手。。");
Object invoke = method.invoke(taget, args);//执行目标方法
System.out.println("洗碗碗。。");
return null;
}
} //主函数
public class Main02 {
public static void main(String[] args) {
//1、创建目标对象
Target taget = new TargetImpl(); //2、创建InvocationHandler对象
InvocationHandler handler = new MyHandler(taget); //3、创建代理对象
Target proxy = (Target) Proxy.newProxyInstance(
taget.getClass().getClassLoader(),
taget.getClass().getInterfaces(),
handler);
//4、通过代理执行方法
proxy.eat();
}
}

2、CGLIB动态代理

  cglib是第三方的工具类,创建代理对象。cglib原理是继承,通过继承目标类,创建它的子类,在子类中重写重写父类中同名的方法,实现功能修改/增强。cglib动态代理要求目标类能够被继承。

  目录展示

  代码展示

//目标类
public class Target {
public void eat(){
System.out.println("吃饭饭。。");
}
} //实现MethodInterceptor接口
public class CglibProxy implements MethodInterceptor {
private Object target; public CglibProxy(Object target) {
this.target = target;
} /**
* @param proxy 代理对象引用
* @param method 被代理对象的方法的描述引用
* @param objects 方法的参数
* @param methodProxy 代理对象的 对目标对象的方法的描述
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object proxy, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("洗手手。。");
method.invoke(target,objects);
System.out.println("洗碗碗。。");
return null;
}
} /主方法测试
public class Main03 {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy(new Target());
Target target = (Target) Enhancer.create(Target.class, cglibProxy);
target.eat();
}
}

反射、静态代理、动态代理(jdk、cglib)的更多相关文章

  1. 静态代理,动态代理,Cglib代理详解

    一.静态代理 新建一个接口 定义一个玩家方法: package com."".proxy.staticc; public interface Iplayer { public vo ...

  2. 【SSH系列】静态代理&&动态代理

    从设计模式说起 代理模式是二十三中设计模式中的一种,代理模式就是指由一个代理主题来操作真实的主题,真实的主题执行具体的业务操作,而代理主题负责其她相关业务,简而言之,代理模式可以由以下三个部分组成: ...

  3. 8、Spring教程之静态代理/动态代理

    为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...

  4. 轻松理解 Java 静态代理/动态代理

    目录 什么是代理模式 定义 代理模式的主要角色 优点 缺点 静态代理 动态代理 JDK原生动态代理 例子 分析 小结 CGLIB动态代理 例子 分析 final类型 其他方案 尾声 理解Java动态代 ...

  5. Java的反射机制和动态代理

    介绍Java注解的时候,多次提到了Java的反射API.与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构.反射API中提供的动态代理也是非常强大的功能,可以原 ...

  6. java静态和动态代理原理

    一.代理概念 为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类 ...

  7. java反射机制与动态代理

    在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...

  8. Java反射机制以及动态代理

    Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...

  9. Java 的静态代理 动态代理(JDK和cglib)

    转载:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是 ...

  10. Spring -07 -AOP [面向切面编程] - 使用注解@+ AspectJ 方式实现环绕/前/后等通知 -超简洁 --静态代理/动态代理{JDK/cglib}

    1.spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解;使用注解来取代配置文件.1.1 引入xmlns:context ,指定扫描范围 <context:comp ...

随机推荐

  1. 带你十天轻松搞定 Go 微服务系列(五)

    序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务(本文) 支付服务 RPC 服务 Auth ...

  2. 运用Spring Aop,一个注解实现日志记录

    运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...

  3. oracle 快速创建用户

    create user  testdb identified by 123456; grant  dba to testdb;

  4. C++智能指针使用说明

    导读 STL提供四种智能指针:auto_ptr.unique_ptr.shared_ptr和weak_ptr.其中auto_ptr是C++98提供的解决方案,C++11以后均已摒弃.所有代码在gcc ...

  5. 【Python爬虫】爬虫利器 requests 库小结

    requests库 Requests 是一个 Python 的 HTTP 客户端库. 支持许多 HTTP 特性,可以非常方便地进行网页请求.网页分析和处理网页资源,拥有许多强大的功能. 本文主要介绍 ...

  6. synchronized、ReentrantLock、volatile

    名词解释 synchronized 是Java中的关键字,是一种同步锁,可以修饰代码块,方法,静态的方法,类.synchronized(Object) 不能用String常量.Integer. Lon ...

  7. keystore文件

    [-] keystore操作 运行时签名文件路径debug 生成签名文件打包时使用 获取MD5和SH1 修改keystore文件密码 修改keystore文件别名 修改keystore文件别名的密码 ...

  8. Java使用DOM方式读写XML

    一.DOM读取 import ***; public class ReadXML { public static void main(String[] args) { try { //DOM Docu ...

  9. Python将py文件编译为exe的方法

    使用PyCharm工具写好的Python程序脚本,怎么将.py文件编译为可执行的.exe文件 前提是已经安装了Python环境. 第一步:在PyCharm内下载安装pyinstalle库或使用CMD安 ...

  10. 【密码学工具】Ciphey和WinDecrypto的使用随笔

    1.Ciphey 官方文档 这个工具安装起来也很容易,用pip下载即可. pip install ciphey -i https://pypi.mirrors.ustc.edu.cn/simple/ ...