动态代理的原理
代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象”取代”原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。

代理模式:可以理解为有两个对象,代理对象和目标对象,代理对象就是帮助我们完成这件事的对象,目标对象就是我们要去做的事情。动态代理就是无论目标对象是什么,都可以通过这样的一个类,去动态生成相对应的代理对象,帮助去完成相应的功能。更像是一个工具类,在任何情况下去生成一个代理对象。

代理对象生成以后,为什么也能帮助我们去实现最终的功能?

①代理对象知道要实现什么功能。②代理对象对接口中的抽象方法的实现,可以利用InvocationHandler来控制代理对象对功能的实现过程。

动态代理的方式
  1) 基于接口实现动态代理: JDK动态代理
  2) 基于继承实现动态代理: Cglib、Javassist动态代理

package com.atguigu.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class ProxyUtil { private MathImpl mathImpl;//目标对象,其实应该是Object public Object getProxy() {
ClassLoader loader = this.getClass().getClassLoader();//类的加载器,创建一个代理类,动态生成一个动态代理类,执行就需要加载,需要指定一个类加载器
Class[] interfaces = mathImpl.getClass().getInterfaces();//目标对象都有那些方法,代理对象通过获取其实现的接口确定,所以代理对象会和目标对象一样实现相同的接口
return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {//第三个参数:代理对象如何实现目标对象的方法
//Java中的所有生成的动态代理类都继承于Proxy类
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(mathImpl, args);//代理模式原则要保证结果的一致性,可以让代理对象调用目标对象的方法就可以保证一致性
}
});
} }

实现对计算器的动态代理:

package com.atguigu.proxy;

import java.util.Properties;

public class Test {

    public static void main(String[] args) {

        /*MathI math = new MathImpl();
int result = math.div(1, 1);
System.out.println(result);*/ ProxyUtil proxy = new ProxyUtil(new MathImpl());
MathI math = (MathI)proxy.getProxy(); //注意不能使用目标对象类型,因为目标类可能还有接口标准之外的方法,所以要强转为接口变量引用
int i = math.div(4, 1);
System.out.println(i); } }
package com.atguigu.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; public class ProxyUtil { private MathImpl mathImpl; //实际中采用Object类型 public ProxyUtil(MathImpl mathImpl) {
super();
this.mathImpl = mathImpl;
} public Object getProxy() {
//获取当前类的类加载器,用来加载代理对象所属类
ClassLoader loader = this.getClass().getClassLoader();
//获取目标对象实现的所有接口的Class,代理类回合目标类实现相同的接口,最终通过代理对象实现功能
Class[] interfaces = mathImpl.getClass().getInterfaces(); return Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() { //代理对象实现功能的方式
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
try {
MyLogger.before(method.getName(), Arrays.toString(args));
Object result = method.invoke(mathImpl, args);//动态代理对象实现功能
MyLogger.after(method.getName(), result);
return result;
} catch (Exception e) {
// TODO: handle exception
MyLogger.throwing();
e.printStackTrace();
} finally {
System.out.println("哪都有我");
}
return null;
}
});
} }
package com.atguigu.proxy;

public interface MathI {

    int add(int i, int j);
int sub(int i, int j);
int mul(int i, int j);
int div(int i, int j); }

interface MathI

package com.atguigu.proxy;

public class MathImpl implements MathI {

    @Override
public int add(int i, int j) {
int result = i + j;
return result;
} @Override
public int sub(int i, int j) {
int result = i - j;
return result;
} @Override
public int mul(int i, int j) {
int result = i * j;
return result;
} @Override
public int div(int i, int j) {
int result = i / j;
return result;
} }

MathImpl

package com.atguigu.proxy;

public class MyLogger {

    public static void before(String methodName, String args) {
System.out.println("method:"+methodName+",arguments:"+args);
} public static void after(String methodName, Object reslut) {
System.out.println("method:"+methodName+",reslut:"+reslut);
} public static void throwing() {
System.out.println("有异常了。。。。");
} }

MyLogger

AOP-动态代理的更多相关文章

  1. 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)

    黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...

  2. Spring学习笔记之aop动态代理(3)

    Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...

  3. String Aop 动态代理例子

    动态代理原理:spring AOP采用动态代理来实现 (1)定义一个接口Boy package aop001; public interface Boy { public void beat(Stri ...

  4. Spring AOP 动态代理 缓存

    Spring AOP应用:xml配置及注解实现. 动态代理:jdk.cglib.javassist 缓存应用:高速缓存提供程序ehcache,页面缓存,session缓存 项目地址:https://g ...

  5. AOP动态代理解析4-代理的创建

    做完了增强器的获取后就可以进行代理的创建了 AnnotationAwareAspectJAutoProxyCreator->postProcessAfterInitialization-> ...

  6. AOP动态代理解析1-标签的解析

    spring.handlers http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespa ...

  7. spring aop 动态代理批量调用方法实例

    今天项目经理发下任务,需要测试 20 个接口,看看推送和接收数据是否正常.因为对接传输的数据是 xml 格式的字符串,所以我拿现成的数据,先生成推送过去的数据并存储到文本,以便验证数据是否正确,这时候 ...

  8. Spring AOP动态代理原理与实现方式

    AOP:面向切面.面向方面.面向接口是一种横切技术横切技术运用:1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物   2.日志处理:3.安全验证 ...

  9. spring AOP 动态代理和静态代理以及事务

    AOP(Aspect Oriented Programming),即面向切面编程 AOP技术,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装 ...

  10. spring源码-aop动态代理-5.3

    一.动态代理,这是一个很强大的东西哦.研发过程中我们会常用很多业务类,但是存在一个问题.如何在不修改源码逻辑的情况下,加入自己的相关逻辑.比如异常处理,日志记录等! 二.Java动态代理的两种方式JD ...

随机推荐

  1. vue 实现高德坐标转GPS坐标

    vue 实现高德坐标转GPS坐标 首先介绍一下常见的几种地图的坐标类型: WGS-84:这是一个国际标准,也就是GPS坐标(Google Earth.或者GPS模块采集的都是这个类型). GCJ-02 ...

  2. linux脚本执行jar包运行

    以下为linux下运行jar包的脚本(只需替换jar包名称): #!/bin/bash #这里可替换为你自己的执行程序,其他代码无需更改 APP_NAME=ruoyi-admin.jar cd `di ...

  3. git冲突解决、线上分支合并、luffy项目后台登陆注册页面分析引入

    今日内容概要 git冲突解决 线上分支合并 登陆注册页面(引入) 手机号是否存在接口 腾讯云短信申请 内容详细 1.git冲突解决 1.1 多人在同一分支开发,出现冲突 # 先将前端项目也做上传到 g ...

  4. 通俗易懂的ArcGis开发快速入门

    前言 本文主要介绍ArcGis的ArcEngine开发,学习时,我们需要放下心里障碍,那就是Gis开发只是普通的软件开发,并不需要专业的GIS知识,就是非常普通的,调用相关的C++开发的COM组件. ...

  5. iptables系列教程(一)| iptables入门篇

    一个执着于技术的公众号 前言 在早期的 Linux 系统中,默认使用的是 iptables 配置防火墙.尽管新型 的 firewalld 防火墙已经被投入使用多年,但是大量的企业在生产环境中依然出于各 ...

  6. 浅谈 UNIX、Linux、ios、android 他们之间的关系

    开源Linux 一个执着于技术的公众号 Unix, 简化形成了Linux,Linux则是Android的内核,而苹果则是使用unix系统作为ios和macos的内核. 几个系统出现的时间 UNIX系统 ...

  7. .Net Core 依赖注入(IOC) 一些简单的使用技巧

    原文链接:https://www.cnblogs.com/ysmc/p/16240534.html .Net Core 在使用IOC后,我们不必再浪费精力在管理实例的生命周期上,交给IOC代替我们管理 ...

  8. 一个Python中优雅的数据分块方法

    背景 看到这个标题你可能想一个分块能有什么难度?还值得细说吗,最近确实遇到一个有意思的分块函数,写法比较巧妙优雅,所以写一个分享. 日前在做需求过程中有一个对大量数据分块处理的场景,具体来说就是几十万 ...

  9. 面试官问:Go 中的参数传递是值传递还是引用传递?

    一个程序中,变量分为变量名和变量内容,变量内容的存储一般会被分配到堆和栈上.而在 Go 语言中有两种传递变量的方式值传递和引用传递.其中值传递会直接将变量内容附在变量名上传递,而引用传递会将变量内容的 ...

  10. VS.NET启动显示ID为XXXX的进程当前未运行

    解决办法:在启动项目根目录下用文本编辑器打开Web项目下的{X}.csproj文件,然后查找 <WebProjectProperties>,将这一对标签之间的内容全部删除,然后再打开项目就 ...