一、反射

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

二、代理

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

三、静态代理

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

代码目录

代码演示

//公共接口
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. Android开发----RecyclerView视图的学习

    RecyclerView RecyclerView是什么? RecyclerView是如今Android开发中最常用的控件,其相较于ListView和GridView的功能更为强大,优化了两者的各种不 ...

  2. 学习Java第10天

    今天所作的工作: 1.线程 2.网络通信 明天工作安排: 做点教材后的案例,复习所学内容 总结一下,10天的时间,看完了Java从入门到精通,只能说是看完了,这里加一个表情笑哭,应该算是知道Java的 ...

  3. Java反射机制及原理

    一.概念 java程序运行时动态的创建类并调用类的方法和属性   二.原理简介 Class<?> clz = Class.forName("java.util.ArrayList ...

  4. Nginx 根据不同的域名来代理转发内部主机-HTTP和HTTPS

    一.需求 由于公司只有一个公网,很多 web 项目都想通过 80 或 443 端口来访问,所以需要 Nginx 充当公司网关. 把唯一的公网 IP 80 端口和 443 端口跟 Nginx 网关主机 ...

  5. 「JSOI2018」机器人

    在本题当中为了方便,我们将坐标范围改至 \((0 \sim n - 1, 0 \sim m - 1)\),行走即可视作任意一维在模意义下 \(+1\). 同时,注意到一个位置只能经过一次,则可以令 \ ...

  6. NOIP2018 Day2T3 保卫王国

    首先不考虑强制要求的话是一个经典问题,令 \(f_{i, 0 / 1}\) 为 \(i\) 选或不选时以 \(i\) 为根的子树的最优答案.那么就有转移 \(f_{u, 0} = \sum f_{v, ...

  7. IDEA导入maven项目时,报各种包找不到--com.sunyard.encrypt.function

    IDEA错误归类 问题描述1 IDEA启动项目时,报maven引入的包找不到 暂时解决办法 问题描述2 IDEA启动项目时,报普通项目引入的包找不到 解决办法 总结: 问题1和问题2的解决办法明显冲突 ...

  8. 使用estimatedRowHeight的优缺点

    使用estimatedRowHeight的优缺点 1.优点 1> 可以降低tableView:heightForRowAtIndexPath:方法的调用频率 2> 将[计算cell高度的操 ...

  9. iOS 模糊、精确搜索匹配功能方法总结 By HL

    字符串搜索主要用于UITableView的搜索功能的筛选,过滤,查询 下面是一些流行的搜索查询方法 一.遍历搜索 for循环 根据要求:精确搜索(判读字符串相等)   模糊搜索(字符串包含) 相关知识 ...

  10. 索引,事务,存储引擎和选择,视图,mysql管理

    一.mysql索引:提高数据库的性能(不用加内存,不用改程序,不用调sql,查询速度就可能提高百倍千倍)索引会占用磁盘空间 CREATE   INDEX   索引名   ON   数据表 (列名or字 ...