实现AOP原理及编程

AOP(面向切面编程)   我们在编写代码时,只想关注逻辑代码的实现。但是我们的程序是要放到服务器上去跑的,我们在代码中如果只有业务逻辑代码。虽然代码简洁,但是万一程序在服务器跑的时候数据出现问题时,没办法快速定位到问题所在。但是将日志等非逻辑代码和我们的逻辑代码放在一起,会使得代码冗余,代码的可读性难度加大。   基于上面的问题,Spring为我们提供了一种解决方案,将业务功能逻辑代码和非功能代码分开来写,然后使用动态代理,将非功能性代码嵌入到功能代码中,这就是所谓的AOP(面向切面编程)。  1、我们要使用Aop对我们的bea 阅读详情

         AOP编程也就是面向切面编程,作为是对面向对象编程的一个重要补充,其应用场景活跃在我们日常开发的角角落落,比如对数据的处理,系统日志的记录,总之,需要在某些业务功能添加一些与业务本身又无关的功能时,你首先想到的应该是AOP。   在实际点的例子,作为java开发的首选框架--spring家族,aop概念就是其核心概念之一,其中的事务,异常以及其本身实现的切面注解都无不是aop的理论应用,如果没有这些东西,我无法想象我在编程时做的项目会是什么样子。

       AOP其底层实现原理是利用注解和代理(动态代理),代理的实现原理则是反射。所以,如果想自己实现aop,反射的知识是必不可少的。有了知识储备,先聊聊我们等下实现aop的思路。这个我们可以借鉴spring对aop的功能介绍,然后针对这些功能,如果自己实现该怎么去完成。在spring中,aop中几个比较重要的概念:切面,通知,连接点。切面描述的是你关注的业务对象在spring中对应的大概是pointcut;通知则是你想做的处理处理嵌入到业务对象中的时机对应spring大概是before(业务进行前嵌入你想嵌入的处理),after(业务成功返回后嵌入想进行的处理),@afterReturn,@afterThrowing等注解;连接点则是触发你想要进行处理的事比如异常抛出,比如某个方法的执行。根据这些概念下面我们要实现这几步:

         1,区分(找到)切面(要被代理的对象)

         2,生成代理对象,并在代理对象里,加入我们想要添加的切面处理

很简单,不过这里我打算换一种方式,1,找到需要添加到切面的操作     2,找到切面    3,生成代理对象,并在代理对象中添加你想做的切面处理            其实就是想说,我们这里比spring的事务aop多做一些事。。。好吧,直接上源码

这里我想使用注解方式找到需要添加到切面的操作,所以先自定义一个注解吧。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface AopAnnotation {

	public String path() default "";
}

因为我们这里用jdk代理生成代理对象,所以,我们这里搞一个接口先(使用cglib其实也一样,就是不用声明接口了,spring中默认对实现接口的对象代理使用jdk代理)

public interface Service {

	public void login1();
	
	public void login2();
}

然后,建一个我们想要做特殊处理的切面类

public class LogsUser implements Service{

	public void login1() {
		System.out.println("user login in 1======");
	}
	public void login2() {
		System.out.println("user login in 2======");
	}
}

再然后,建一个我们想做的处理类并使用我们上面建好的自定义注解进行标注,我们给path赋值为刚建好的切面类,等下用这个找切面,并把找到的切面类进行代理,对其所有方法都在调用方法前加printlog日志,其实就相当于@Before注解(的jdk代理实现)

public class AopService {

	@AopAnnotation(path="LogsUser")
	public void printLog() {
		System.out.println("++++++++++++++ before login logs===++++++++++");
	}
	
}

再然后,就是我们经常看到spring启动时加载生成的一大堆代理类的过程了,主要是实现找到项目下所有使用自定义的切面注解,并生成相对应的代理。我简单的把他放在一个main中,主要也为了看效果。君可自行理解

public class AnnotationTest {

	public static void main(String[] s) {
		test2();
	}
	
	/**
	 * 实现aop
	 */
	public static void test2() {
		String path = AnnotationTest.class.getResource("/").getPath();
		System.out.println("项目根路径:"+path);
		File bootFile = new File(path);
		LinkedList<File> list = new LinkedList<File>();
		Map<String,String> map= new HashMap<>();//存放文件对应的文件名
		LinkedList<String> list1 = new LinkedList<>();//存放文件对应的包路径
		if(bootFile.isDirectory()) {
			File fs[] = bootFile.listFiles();
			for(File file : fs) {
				list.add(file);
				list1.add("");
			}
			File tempFile = list.removeFirst();
			String tempPath =list1.removeFirst();
			while(tempFile!=null) {//如果是文件夹则遍历
				if(tempFile.isDirectory()) {
					File[] fa = tempFile.listFiles();
					for(File file : fa) {
						list.addLast(file);
						if(tempPath!=null&&!tempPath.equals("")) {
							list1.addLast(tempPath+"."+tempFile.getName());
							if(!file.isDirectory()) {
								map.put(file.getName().split("\\.")[0], tempPath+"."+tempFile.getName());
							}
						}else {
							list1.addLast(tempFile.getName());
							if(!file.isDirectory()) {
								map.put(file.getName().split("\\.")[0], tempFile.getName());
							}
						}
					}
				}else {//是文件而不是文件夹,判断是否存在注解
					
					String javaFile = tempFile.getName().split("\\.")[0];
					try {
						if(tempFile.getName().split("\\.")[1].equals("class")) {
							System.out.println(tempFile.getName());
							System.out.println(tempPath+"."+javaFile);
							Class javaClass = Class.forName(tempPath+"."+javaFile);
//							AopAnnotation aopAn = (AopAnnotation)javaClass.getDeclaredAnnotation(AopAnnotation.class);
//							Class cl = Class.forName(aopAn.path());
							Method[] methods = javaClass.getDeclaredMethods();
							for(Method method : methods) {
//								System.out.println("------------------");
								AopAnnotation aopAN = null;
								if(method.isAnnotationPresent(AopAnnotation.class)) {
									aopAN = method.getAnnotation(AopAnnotation.class);//找到注解
									Class cl = Class.forName(map.get(aopAN.path())+"."+aopAN.path());//找到切面类
									Object proxyObject = null;
									try {
										proxyObject =  cl.newInstance();
									} catch (InstantiationException | IllegalAccessException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									MyInvocationHandler handler = new MyInvocationHandler();
									Annotation annatation = javaClass.getAnnotation(AopAnnotation.class);
									try {
										handler.setProxyObject(proxyObject, method, null, javaClass.newInstance());
									} catch (InstantiationException | IllegalAccessException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
									Service proxyUser = (Service) Proxy.newProxyInstance(cl.getClassLoader(), proxyObject.getClass().getInterfaces(), 
											handler);
									System.out.println("++++++++++++++++");
									proxyUser.login1();
									proxyUser.login2();
								}
							}
						}
						
						//暂时先不对class的filed进行设置..........................................
						
					} catch (ClassNotFoundException e) {
						System.out.println(e);
						System.out.println("============查找class出错============");
					}
					
				}
				if(list.size()>0) {
					tempFile = list.removeFirst();
					tempPath = list1.removeFirst();
				}else {
					tempFile=null;
				}
				
			}
		}else {
			System.out.println("no file behind the file");
		}
	}
	

既然是使用jdk代理,怎么少得了InvocationHandler呢。

class MyInvocationHandler implements InvocationHandler{

	Object proxyObject;//要被代理的对象
	Method preProxyMethod;//我们的特殊处理(这里就是加了我们自定义注解的方法)
	Object[] args;//上面方法的参数
	Object object;//上面方法所在的对象,或者在这里传一个class对象,然后你在自己生成其对象也行
	public void setProxyObject(Object proxyObject,Method method,Object[] args,Object object) {
		this.args=args;
		this.proxyObject = proxyObject;
		this.preProxyMethod = method;
		this.object = object;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		preProxyMethod.invoke(object, this.args);//特殊处理织入
		Object reObject = method.invoke(proxyObject, args);
		return reObject;
	}
	
}

ok,把这些代码,复制回去应该就是能运行出结果的,

 

虽然代码有点乱,但我相信上面的代码很简单。其实自己也是可以实现简单的aop的,aop说起来高大上,其实也没那么遥远,不过,我个人认为这种思想很重要,最起码,以后假如有一天让你自己去在非spring环境下处理问题,或者就是你自己写一个项目,脚本用不到spring时,你就可以用这招很明显的减少你的工作量了。

 

【Spring】深入学习AOP编程思想的实现原理和优势 阅读详情

相关推荐

Spring AOP的实现原理与编程

Spring AOP是Spring框架的一个模块,用于实现AOP编程。AOP是一种编程范式,它允许将横切关注点模块化,并将其应用到应用程序的多个部分中。在传统的面向对象编程中,横切关注点往往与应用程序的核心逻辑混杂在一起,导致代码的可读性和可维护性降低。AOP通过将这些关注点从核心逻辑中分离出来,使得代码更加清晰、可重用和可扩展。Spring AOP通过基于代理的方式实现AOP编程。它基于运行时动态代理机制,为目标对象生成一个代理对象,该代理对象能够拦截并织入横切逻辑。

DevRevolt的博客 88

AOP——面向切面编程

AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构。 OOP(Object Oriented Programming)面向对象编程,是一种编程思想,所以,AOP也是一种编程思想,只是他们两个是不同的编程范式。

m0_62912377的博客 1万+

(1)大蚂蚁即时通讯

即时通讯软件BigAnt(大蚂蚁)是杭州艾朴软件推出的一个”企业级”的即时通讯平台。该平台专为企业,其他企事业单位和政府单位而设计,目的就是为了增强内部沟通能力,提高内部员工的工作效率;同时服务器就直接置于单位内部,所有信息由单位自己管理,让单位以更安全、更可伸缩和更易于管理的方式灵活方便地使用协同和通信服务的功能! BigAnt(大蚂蚁)即时通讯软件包括服务器端和客户端。客户端功能包括单位

少安的砖厂 2235

AOP(面向切面编程)全面解析

AOP(Aspect-Oriented Programming),即面向切面编程,是一种通过分离应用中的横切关注点(Cross-Cutting Concerns)来实现模块化的软件开发范式。AOP的核心思想是将某些通用功能(如日志、事务管理、异常处理等)从业务逻辑代码中剥离出来,形成独立的切面模块。AOP允许我们在不修改原始代码的情况下为程序添加额外的功能,从而实现代码的解耦和复用。通俗地说,AOP是通过切面来定义和隔离特定操作的编程方式,使得开发者可以在程序的不同部分“切入”这些操作。

hello.reader 7077

第一天(点亮led灯+led灯闪烁)——Arduino uno R3 学习之旅

发光二极管(Light Emitting Diode,简称LED)是一种能够将电能转化为光能的固态的半导体器件。长脚为阳极短脚为阴极电流必须从长脚流入从短脚流出方可点亮LED##杜邦线杜邦线:是导线中的一种,杜邦线端部有两种接头形式:带针的一种称为公头,带孔的一种称为母头,如下图所示:说明:与电源相连接时,一般采用红色杜邦线,与地连接时采用黑色杜邦线。

qwsbcjendb的博客 1130

CCS TMSC6748 报错Error connecting to the target: (Error -600 @ 0x0)

CCS TMSC6748 报错Error connecting to the target:(Error -600@ 0x0)

AS_the_deer1717的博客 6636

AOP 面向切面编程的实现原理

AOP是基于IOC的Bean加载来实现的,所以理解Spring AOP的初始化必须要先理解Spring IOC的初始化。然后就能找到,即parseCustomElement方法找到parse aop:aspectj-autoproxy的handler(org.springframework.aop.config.AopNamespaceHandler)

SevenCoding的博客 1157

添加odbc数据源时的一些问题和解决办法

pl/sql

Mr_Syh的博客 9644

Spring AOP切面编程实现原理

Spring AOP是Spring框架中极为重要的核心功能,和Spring IOC并称为Spring的两大核心模块。顾名思义,AOP 即 Aspect Oriented Programming,翻译为面向切面编程。OOP面向对象编程是纵向地对一个事物的抽象,一个对象包括静态的属性信息、动态的方法信息等。而AOP是横向地对不同事物的抽象,属性与属性、方法与方法、对象与对象都可以组成一个切面,而用这种思维去设计编程的方式叫做面向切面编程。Spring AOP是利用CGLIB 和 JDK 动态代理。

weixin_41821642的博客 396

PyTorch实战:用FGSM攻击MNIST分类器(附可视化对比)

本文通过PyTorch实战演示了如何使用FGSM对抗攻击方法攻击MNIST手写数字分类器。文章详细解析了FGSM攻击原理,提供了从环境搭建、模型准备到攻击实施、可视化对比的完整代码实战流程,并探讨了对抗样本的生成与模型鲁棒性评估。

3a9bq4r8t2y的博客 216

VS Code下载安装与使用教程

VSCode下载安装与使用教程

weixin_46713695的博客 4万+

Aop切面编程原理和Spring实现

AOP切面编程一般可以帮助我们在不修改现有代码的情况下,对程序的功能进行拓展,往往用于实现 日志处理,权限控制,性能检测,事务控制等AOP实现的原理就是动态代理,在有接口的情况下,使用JDK动态代理,在没有接口的情况下使用cglib动态代理类里面那些可以被增强的方法,这些方法称之为连接点表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point实际被增强的方法,称之为切入点。

m0_37135879的博客 1360

2026华为OD机试(Python)真题【E卷+A卷+B卷+C卷+D卷】目录+在线OJ

华为OD机试真题题库【E卷+A卷+B卷+C卷+D卷】目录,Python实现。

MISAYAONE的博客 29万+

第十四章、AOP编程实现原理

1.AOP概念 AOP (Aspect Oriented Programing) ⾯向切⾯编程 = Spring动态代理开发 以切⾯为基本单位的程序开发,通过切⾯间的彼此协同,相互调⽤,完成程序的构建 切⾯ = 切⼊点 + 额外功能 OOP (Object Oritened Programing) ⾯向对象编程 Java 以对象为基本单位的程序开发,通过对象间的彼此协同,相互调⽤,完成程序的构建 POP (Producer Oriented Programing) ⾯向过程(⽅法、函数)编程 C 以过程为基

豆恭梓的博客 671

WorkBuddy KiCad 实战:国产 AI 搭子不只会写代码,传感器板从零走到可审查

真正可用的 PCB 教程不能承诺“一键打样”。本课把 WorkBuddy 放在需求拆分、文件生成和审查记录的位置,KiCad 负责 ERC、DRC 与制造文件,工程师负责最终判断。 本课不会用“AI 一键完成”制造错觉,而是把 WorkBuddy、KiCad 8.0、Python 3.11 与人工审阅组成一条可复现链路。你会从“已确认的接口表、器件库来源、板框与电源方案”出发,得到“KiCad 工程、原理图、初始 BOM、ERC 报告与审查记录”,并学会用真实命令、错误信号和停止条件判断成果能不能进入下一阶

yueyeguzhuo的专栏 222

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

AOP实现原理:从命令式编程和声明式编程说起

面向方面编程(Aspect Oriented Programming,简称AOP)是一种声明式编程(Declarative Programming)。声明式编程是和命令式编程(Imperative Programming)相对的概念。我们平时使用的编程语言,比如C++、Java、Ruby、Python等,都属命令式编程。命令式编程的意思是,程序员需要一步步写清楚程序需要如何做什么(How to d

我的学习历程 1630

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

AOP的底层实现原理,基于注解的AOP编程,切入点复用,AOP开发中同一个业务类中方法的相互调用

1.AOP编程 1.1 AOP概念 AOP (Aspect Oriented Programing) 面向切面编程 Spring动态代理开发 以切面为基本单位的程序开发,通过切面间的彼此协同,相互调用,完成程序的构建 切面 = 切入点 + 额外功能 OOP (Object Oritened Programing) 面向对象编程 Java 以对象为基本单位的程序开发,通过对象间的彼此协同,相互调用,完成程序的构建 POP (Producer Oriented Programing) 面向过程(方法

tuc1997的博客 769

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Spring AOP 编程原理和实现

通过代理讲解spring aop的实现过程和原理

tonysong111073的专栏 395

深入浅出Spring AOP面向切面编程实现原理方法

1. 什么是AOP AOP (Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现在不修改源代码的情况下,给程序动态统一添加功能的一种技术,可以理解成动态代理。是Spring框架中的一个重要内容。利用 AOP 可以对业务逻辑的各个部分进行隔离,使业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率 2. Spring AOP ①. AOP 在Spring中的作用 提供声明式事务;允许用户自定义切面 ②. AOP 的基本概念 横切关注

weixin_51495453的博客 505
上一篇: spring boot将session存储到redis后无法取到session
下一篇: 对于java中线程的一些思考
孩子不是海子
博客等级 码龄11年 14粉丝 28原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值