初识AOP

什么是AOP:aspect oridented programming,面向切面编程,是一种在运行时,动态代理实现对传统编程的补充。

AOP用途:简化代码。面向对象开发时,有很多重复的代码,现在就是通过分层,对代码简化。

通过例子讲述如何使用AOP:

1、添加jar包:

2、添加spring xml文件,在文件中配置,为目标对象生成动态代理对象。如图所示:

3、创建ICalculatorService接口,和实现类CaluculatorService,代码分贝如下:

ICalculatorService代码:

package com.jd.calculator.service;

public interface ICalculatorService {
	
	int mul(int a, int b);
	
	int div(int a, int b);
}

CaluculatorService代码:

package com.jd.calculator.service;

import org.springframework.stereotype.Service;

@Service
public class CalculatorService implements ICalculatorService {

	@Override
	public int mul(int a, int b) {
		return a*b;
	}

	@Override
	public int div(int a, int b) {
		return a/b;
	}

}

4、创建计算器切面类,CalculatorAspect类

主要运用以下四种注解:@Before @After@AfterReturning@AfterThrowing

代码如下:在代码中详细说明了各个注解的增强作用,以及注解的区别,以及为了简化切入点表达式而新定义的pointcut注解

package com.jd.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect//声明该类是切面类
@Component//声明该类对象存在在Ioc容器中
public class CalculatorAspect {
	
        //用于简化注解:通过观察发现CalculatorAspect类中@Before,@After,@AfterReturning、@AfterThrowing和@Around注解中切入点表达式相同,为了简化代码,可以单独自定义一个@Pointcut注解修饰的空方法,通过该方法可以简化@Before,@After,@AfterReturning、@AfterThrowing和@Around注解中的切入点表达式,
	@Pointcut("execution(public int com.jd.calculator.service.CalculatorService.*(int,int))")
	public void Pointcut(){
		
	}
	
	//前置增强,目标方法执行前执行
	@Before("Pointcut()")
	public void befor(JoinPoint jp) {
		Object [] arges =jp.getArgs();
//		for (Object object : arges) {
//			System.out.println(object);
//		}
		Signature signature =jp.getSignature();
		String name = signature.getName();
		System.out.println("The "+name+" method begins.");
		System.out.println("The "+name+" method rags:["+arges[0]+","+arges[1]+"]");
	}
	
	//后置增强,目标方法执行完毕执行
	@After("Pointcut()")
	public void after(JoinPoint jp) {
		Signature signature =jp.getSignature();
		String name = signature.getName();
		System.out.println("The "+name+" method ends.");
	}
	
	//返回增强,目标方法执行return以后执行
	//后置增强和返回增强的区别:返回增强比后置增强后执行。如果目标方法出现异常则返回增强不执行
	@AfterReturning(value="Pointcut())",returning="result")
	public void afterReturning(JoinPoint jp,Object result) {
		Signature signature =jp.getSignature();
		String name = signature.getName();
		System.out.println("Result of the "+name+" method:"+result);
	}
	
	//异常增强,目标方法出现异常时执行
	@AfterThrowing(value="Pointcut()",throwing="e")
	public void afterThrowing(JoinPoint jp,Exception e) {
		Signature signature =jp.getSignature();
		String name = signature.getName();
		System.out.println("Exception of the method "+name+": "+e);
	}
	
}

5、创建test类,用于测试:

test代码如下:

package com.jd.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jd.calculator.service.ICalculatorService;

public class test {

	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext applacation = new ClassPathXmlApplicationContext("app.xml");
		ICalculatorService calculatorService = applacation.getBean(ICalculatorService.class);
		//System.out.println(calculatorService.div(8, 2));
		calculatorService.div(8, 2);
		applacation.close();
	}
}

执行结果如下:

说明以下几点:

①:返回增强比后置增强后执行。如果目标方法出现异常则返回增强不执行

②:各个增强的执行顺序如注释说写。

将div的分母改为0.测试异常增强是否可以如愿执行。

结果如下:说明如愿执行了。

------------------------------------------------------------------------------------------------------------------------------------

还可以将四种增强通过一个注解来写,就是@Around。

代码如下:

jd.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class CalculatorAspect {
	
	@Pointcut("execution(public int com.jd.calculator.service.CalculatorService.*(int,int))")
	public void Pointcut(){
		
	}

	//环绕增强:目标方法执行前后都可以织入增强处理
	//环绕增强和其他增强的区别:@Before、@After、@AfterRunning和@AfterThrowing修饰的方法没有返回值;而@Around修饰的方法必须有返回值,返回值为目标方法的返回值
		@Around("Pointcut()")
		public Object around(ProceedingJoinPoint jp) {
			Object result = null;
			String name = jp.getSignature().getName();
			Object [] arges =jp.getArgs();

			try {
				try {
					//前置增强
					System.out.println("The "+name+" method begins.");
					System.out.println("The "+name+" method rags:["+arges[0]+","+arges[1]+"]");
					//执行目标对象内的方法
					result = jp.proceed();
				}finally {
					//后置增强
					System.out.println("The "+name+" method ends.");
				}
				//返回增强
				System.out.println("Result of the "+name+" method:"+result);
			} catch (Throwable e) {
				//异常增强
				System.out.println("Exception of the method "+name+": "+e);
			}
			
			return result;
		}

}

执行结果是一样的,这里就不再赘述。

Spring AOP的流程图如下: 1. 首先,通过Spring的环境配置将AOP功能添加到应用程序中。 2. 当应用程序执行时,Spring框架会在背后为每个被代理的bean创建一个代理对象。 3. 当调用被代理对象的方法时,Spring框架会首先检查是否有与该方法相关联的通知。 4. 如果有相关联的通知,Spring框架会在方法的不同执行点将通知织入到方法中。 5. 通知可以在方法执行之前、之后或异常发生时执行,以实现横切关注点的功能。 6. 一旦通知被织入到方法中,Spring框架会继续执行方法的原始逻辑。 7. 在方法执行完成后,Spring框架可以执行其他相关的通知,例如返回通知或异常通知。 8. 最后,Spring框架会将最终的结果返回给调用方。 总结来说,Spring AOP的流程是将通知织入到被代理对象的方法中,以实现在方法执行前、执行后或异常发生时执行特定操作的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [spring事务的底层实现流程图](https://download.csdn.net/download/weixin_43860634/88136159)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Spring ----> aop初识与 切面编程 实现方式(八)](https://blog.csdn.net/weixin_46163590/article/details/116348840)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Spring AOP执行流程图&源码分析](https://blog.csdn.net/lbh199466/article/details/111395360)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值