Java实现AOP代理的三种方式详解

目录
  • 1、JDK实现
  • 2、CGLIB实现
  • 3、boot注解实现【注意只对bean有效】

业务场景:首先你有了一个非常好的前辈无时无刻的在“教育”你。有这么一天,它叫你将它写好的一个方法进行改进测试,这时出现了功能迭代的情况。然后前辈好好“教育”你的说,不行改我的代码!改就腿打折!悲催的你有两条路可走,拿出你10年跆拳道的功夫去火拼一波然后拍拍屁股潇洒走人,要么就是悲催的开始百度。。。这时你会发现,我擦怎么把AOP代理这种事给忘了?【其实在我们工作中很少去手写它,但是它又是很常见的在使用(控制台日志)】

怎么办?打赢送手镯,打输睡大觉?

兄弟,信我的!

写吧。。。

AOP是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程的一种补充和完善,它以通过预编译方式和运行期动态代理方式实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。

利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

简单说就是在不影响原有功能代码的情况下进行扩展,浸入少。

废话不多说,开搞!

1、JDK实现

MyAop
package com.example.quasar.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//继承InvocationHandler接口实现
public class MyAop implements InvocationHandler {
    private Object object;

    public MyAop(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //前置
        System.out.println("前置运行");
        Object invoke = method.invoke(this.object, args);
        //后置
        System.out.println("后置运行");
        return invoke;
    }
}

IndexService

package com.example.quasar.service;

public interface IndexService {
    public void run();
    public void run1();
}

IndexServiceImpl

package com.example.quasar.service.impl;

import com.example.quasar.service.IndexService;

public class IndexServiceImpl implements IndexService {
    @Override
    public void run() {
        System.out.println("运行了");
    }

    @Override
    public void run1() {
        System.out.println("运行了1");
    }
}

QuasarApplication

package com.example.quasar;
import com.example.quasar.aop.MyAop;
import com.example.quasar.service.IndexService;
import com.example.quasar.service.impl.IndexServiceImpl;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.lang.reflect.Proxy;

@SpringBootApplication
public class QuasarApplication {

    public static void main(String[] args) {
        //实现类实例化
        IndexService indexService = new IndexServiceImpl();
        //将实例传入aop
        MyAop myAop = new MyAop(indexService);
        //通过Proxy.newProxyInstance实现代理
        IndexService o = (IndexService) Proxy.newProxyInstance(IndexServiceImpl.class.getClassLoader(), new Class[]{IndexService.class}, myAop);
        //执行实现方法
        o.run();
        o.run1();
    }

}

执行结果

2、CGLIB实现

如果项目中,已经使用了Spring,可以忽略导入上述两个包。因为在spring-core中已经集成了。否则需要引入该包,百度去找。

MyAop

package com.example.quasar.aop;

public class MyAop {
    public void befor() {
        System.out.println("befor...");
    }
    public void after() {
        System.out.println("after...");
    }
}

IndexService

package com.example.quasar.service;

public interface IndexService {
    public void run();
    public void run1();
}

IndexServiceImpl

package com.example.quasar.service.impl;

import com.example.quasar.service.IndexService;

public class IndexServiceImpl implements IndexService {
    @Override
    public void run() {
        System.out.println("运行了");
    }

    @Override
    public void run1() {
        System.out.println("运行了1");
    }
}

QuasarApplication

package com.example.quasar;
import com.example.quasar.aop.MyAop;
import com.example.quasar.service.IndexService;
import com.example.quasar.service.impl.IndexServiceImpl;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

@SpringBootApplication
public class QuasarApplication {

    public static void main(String[] args) {
        //实现类实例化
        IndexService indexService = new IndexServiceImpl();
        // 代理类 ,采用cglib,底层创建目标类的子类
        MyAop myAop = new MyAop();
        // 核心类
        Enhancer enhancer = new Enhancer();
        //确定父类
        enhancer.setSuperclass(indexService.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                //前置
                myAop.after();
                // 执行目标类的方法
                Object obj = method.invoke(indexService, args);
                //后置
                myAop.befor();
                return obj;
            }
        });
        // 3.4 创建代理
        IndexService proxService = (IndexService) enhancer.create();
        proxService.run();
        proxService.run1();
    }

}

执行结果

3、boot注解实现【注意只对bean有效】

MyAop

package com.v1.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAop {
    //*号作用:com.v1.service.impl下的所有类和所有方法
    @Before(value = "within(com.v1.service.impl.*)")
    public void before(JoinPoint joinPoint) {
        System.out.println("before开始执行查询.......");
        System.out.println("正在执行的目标类是: " + joinPoint.getTarget());
        System.out.println("正在执行的目标方法是: " + joinPoint.getSignature().getName());
    }
    //*号作用:com.v1.controller下的所有类和所有方法
    @Around(value = "execution(* com.v1.controller.*.*(..))")
    public Object aroud(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("aroud环绕通知开始.......");
        System.out.println("执行的目标类 = " + proceedingJoinPoint.getTarget());
        System.out.println("执行的目标方法 = " + proceedingJoinPoint.getSignature().getName());
        // 必须方法目标方法
        Object proceed = proceedingJoinPoint.proceed();
        System.out.println("aroud环绕通知结束.......");
        // 将目标方法的返回值进行返回,否则调用目标方法的方法无法获取到返回值
        return proceed;
    }

}

非常简单,直接就根据注解进行代理了!

注解参数可以具体在咱们csdn平台去查一下,有很多文章讲的很细的!

执行结果

发个请求跑一下

以上就是Java实现AOP代理的三种方式详解的详细内容,更多关于Java AOP代理的资料请关注我们其它相关文章!

(0)

相关推荐

  • Java JDK动态代理(AOP)用法及实现原理详解

    Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我们在用Spirng和Mybatis的时候,要理解怎么使用的. 1.什么是代理? 代理,在我们日常生活之中就有体现,代购,中介,换ip,商家等等. 比如有一家美国的大学,可以对全世界招生.留学中介(代理 ) 留学中介(代理):帮助这家美国的学校招生,中介是学校的代理中介是代替学校完成招生功能 代理特点

  • 详解Java反射实现Aop代理

    利用反射生成JDK的动态代理,也就是AOP中的AOP代理,代替目标对象,从而在代码中织入增强. 定义代理接口 由于JDKf动态代理只能为接口创建动态代理,故先定义接口,假定我们需要对数据的Save方法添加事务处理,我们有一个UserDao接口,里面有一个Save方法,代码如下: public interface UserDao { public void save(); } 定义代理实现 下面具体来实现接口定义的Save方法,我们采用下面的代码来实现. public class UserDaoI

  • Java动态代理实现AOP

    目前整个开发社区对AOP(Aspect Oriented Programing)推崇备至,也涌现出大量支持AOP的优秀Framework,--Spring, JAC, Jboss AOP 等等.AOP似乎一时之间成了潮流.Java初学者不禁要发出感慨,OOP还没有学通呢,又来AOP.本文不是要在理论上具体阐述何为AOP, 为何要进行AOP . 要详细了解学习AOP可以到它老家http://aosd.net去瞧瞧.这里只是意图通过一个简单的例子向初学者展示一下如何来进行AOP. 为了简单起见,例子

  • java使用动态代理来实现AOP(日志记录)的实例代码

    下面是一个AOP实现的简单例子: 首先定义一些业务方法: 复制代码 代码如下: /** * Created with IntelliJ IDEA. * Author: wangjie  email:tiantian.china.2@gmail.com * Date: 13-9-23 * Time: 下午3:49 */public interface BussinessService {    public String login(String username, String password

  • Java动态代理和AOP应用示例

    本文实例讲述了Java动态代理和AOP应用.分享给大家供大家参考,具体如下: 一 点睛 动态代理在AOP(Aspect Orient Program,即面向切面编程)里被称为AOP代理,AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法.但AOP代理中的方法与目标对象的方法存在差异:AOP代理里的方法可以在执行目标方法之前.之后插入一些通用处理. 二 代码 Dog.java public interface Dog { // info方法声明 void info(); // run方法

  • 详解使用Java原生代理实现AOP实例

    一说到AOP,大家一定会想到spring,因为这东西实在是太强大了.但是大家一定要清楚,AOP是一只编程思想,而Spring仅仅是AOP的一种实现罢了. 首先百度下: 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务

  • Java JDK动态代理(AOP)的实现原理与使用详析

    本文主要给大家介绍了关于Java JDK动态代理(AOP)实现原理与使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对

  • Java实现AOP代理的三种方式详解

    目录 1.JDK实现 2.CGLIB实现 3.boot注解实现[注意只对bean有效] 业务场景:首先你有了一个非常好的前辈无时无刻的在“教育”你.有这么一天,它叫你将它写好的一个方法进行改进测试,这时出现了功能迭代的情况.然后前辈好好“教育”你的说,不行改我的代码!改就腿打折!悲催的你有两条路可走,拿出你10年跆拳道的功夫去火拼一波然后拍拍屁股潇洒走人,要么就是悲催的开始百度...这时你会发现,我擦怎么把AOP代理这种事给忘了?[其实在我们工作中很少去手写它,但是它又是很常见的在使用(控制台日

  • java打jar包的几种方式详解

    一.制作只含有字节码文件的jar包 我们先来看只含有字节码文件,即只含有class文件的jar包怎么制作,这是最简单的形式 1.最简单的jar包--直接输出hello 最终生成的jar包结构 META-INF Hello.class 方法步骤 (1)用记事本写一个Hello.java的文件 class Hello{     public static void main(String[] agrs){         System.out.println("hello");     }

  • Java中遍历ConcurrentHashMap的四种方式详解

    这篇文章主要介绍了Java中遍历ConcurrentHashMap的四种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 方式一:在for-each循环中使用entries来遍历 System.out.println("方式一:在for-each循环中使用entries来遍历");for (Map.Entry<String, String> entry: map.entrySet()) { System.out.pr

  • Pandas保存csv数据的三种方式详解

    目录 方法一 方法二 方法三 补充 方法一 import os import pandas as pd path = 'data/train/' img_label_list=[] testList = os.listdir(path) for file in testList: label='aa' img_label_list.append([file, label]) df1 = pd.DataFrame(data=img_label_list, columns=['id', 'label

  • Python图片存储和访问的三种方式详解

    目录 前言 数据准备 一个可以玩的数据集 图像存储的设置 LMDB HDF5 单一图像的存储 存储到 磁盘 存储到 LMDB 存储 HDF5 存储方式对比 多个图像的存储 多图像调整代码 准备数据集对比 单一图像的读取 从 磁盘 读取 从 LMDB 读取 从 HDF5 读取 读取方式对比 多个图像的读取 多图像调整代码 准备数据集对比 读写操作综合比较 数据对比 并行操作 前言 ImageNet 是一个著名的公共图像数据库,用于训练对象分类.检测和分割等任务的模型,它包含超过 1400 万张图像

  • Python绘制散点密度图的三种方式详解

    目录 方式一 方式二 方式三 方式一 import matplotlib.pyplot as plt import numpy as np from scipy.stats import gaussian_kde from mpl_toolkits.axes_grid1 import make_axes_locatable from matplotlib import rcParams config = {"font.family":'Times New Roman',"fo

  • Python写入MySQL数据库的三种方式详解

    目录 场景一:数据不需要频繁的写入mysql 场景二:数据是增量的,需要自动化并频繁写入mysql 方式一 方式二 总结 大家好,Python 读取数据自动写入 MySQL 数据库,这个需求在工作中是非常普遍的,主要涉及到 python 操作数据库,读写更新等,数据库可能是 mongodb. es,他们的处理思路都是相似的,只需要将操作数据库的语法更换即可. 本篇文章会给大家分享数据如何写入到 mysql,分为两个场景,三种方式. 场景一:数据不需要频繁的写入mysql 使用 navicat 工

  • Android Flutter实现搜索的三种方式详解

    目录 示例 1 :使用搜索表单创建全屏模式 编码 示例 2:AppBar 内的搜索字段(最常见于娱乐应用程序) 编码 示例 3:搜索字段和 SliverAppBar 编码 结论 示例 1 :使用搜索表单创建全屏模式 我们要构建的小应用程序有一个应用程序栏,右侧有一个搜索按钮.按下此按钮时,将出现一个全屏模式对话框.它不会突然跳出来,而是带有淡入淡出动画和幻灯片动画(从上到下).在圆形搜索字段旁边,有一个取消按钮,可用于关闭模式.在搜索字段下方,我们会显示一些搜索历史记录(您可以添加其他内容,如建

  • Tensorflow 2.4加载处理图片的三种方式详解

    目录 前言 数据准备 使用内置函数读取并处理磁盘数据 自定义方式读取和处理磁盘数据 从网络上下载数据 前言 本文通过使用 cpu 版本的 tensorflow 2.4 ,介绍三种方式进行加载和预处理图片数据. 这里我们要确保 tensorflow 在 2.4 版本以上 ,python 在 3.8 版本以上,因为版本太低有些内置函数无法使用,然后要提前安装好 pillow 和 tensorflow_datasets ,方便进行后续的数据加载和处理工作. 由于本文不对模型进行质量保证,只介绍数据的加

  • Flutter控制组件显示和隐藏三种方式详解

    目录 方式一:if语句控制 方式二:Offstage组件 方式三: Visibility Offstage和Visibility的区别: 方式一:if语句控制 // 例如: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ if(a=="显示") Text("显示"), Offstage( offstage: false, child: Text("显示"), ),

随机推荐