ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

详述SpringAOP

2020-03-07 15:42:45  阅读:217  来源: 互联网

标签:详述 getName System println import SpringAOP org public


目录

 

一、AOP是什么

二、为什么要用AOP

三、AOP中的几种方法注释

(1)@Before

(2)@After

(3)@AfterReturning 

(4)@AfterThrowing 

(5)@Around


一、AOP是什么

Aspect Oriented Programming(AOP)是较为热门的一个话题。AOP,国内大致译作“面向切面编程”。

“面向切面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。有些人认为“OOP/OOD11即将落伍,AOP是新一代软件开发方式”。显然,发言者并没有理解AOP的含义。Aspect,的确是“方面”的意思。不过,汉语传统语义中的“方面”,大多数情况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要从几个方面来看待”,往往意思是:需要从不同的角度来看待同一个事物。这里的“方面”,指的是事物的外在特性在不同观察角度下的体现。而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。

可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。

在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

二、为什么要用AOP

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

三、AOP中的几种方法注释

现在编写程序实现如下功能,计算两个数的商,且有以下输出:

要求详细输出调用方法的信息及传入参数还有执行阶段信息。 假设我们直接将字符写入方法内,像这样:

public int div(int a, int b) {
		System.out.println(this.getClass().getName()+":The div method begins.");
		System.out.println(this.getClass().getName()+":Parameters of the div method: ["+a+","+b+"]");
		int result = a/b;
		System.out.println(this.getClass().getName()+":Result of the div method:"+result);
		System.out.println(this.getClass().getName()+":The div method ends.");
		return result;
	}

则当我们再定义多个方法时,代码重复太多,于是我们定义另外一个方法:

private void advice(String method,int a,int b) {
		System.out.println(this.getClass().getName()+":The "+method+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+method+":["+a+","+b+"]");
	}

但这样依然不够让我们的代码得到简化,于是就要用到AOP。

首先定义SpringConfig文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
	
	<context:component-scan base-package="com.jd"></context:component-scan>
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

定义ComputerService类:

import org.springframework.stereotype.Service;

@Service
public class ComputerService implements IComputerService {

	public int add(int a, int b) {
		int result = a+b;
		return result;
	}

	public int div(int a, int b) {
		int result = a/b;
		return result;
	}
	
}

定义ComputerAOP类(先不添加内容):


import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ComputerAOP {
	
	
}

定义Test类用于执行方法:

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.jd.computer.service.IComputerService;

public class Test {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		IComputerService computerService = applicationContext.getBean(IComputerService.class);
		System.out.println(computerService.getClass().getName());
		System.out.println(computerService.div(1, 1));
		applicationContext.close();
	}
}

当我们在执行某个方法时大概有三个阶段:开始,结束,返回结果,接下来就介绍AOP中的几个方法注释

(1)@Before

Before即为前置方法,即在调用目标方法前执行的方法。定义如下:

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

@Aspect
@Component
public class ComputerAOP {
	
	@Before("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void before(JoinPoint jp) {//JoinPoint 连接点对象
		Object [] args = jp.getArgs();//得到方法中传入的参数
		
		Signature signature = jp.getSignature();//得到切入点调用的的目标类的方法
		String name = signature.getName();//得到目标方法的名字
		System.out.println(this.getClass().getName()+":The "+name+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+name+":["+args[0]+","+args[1]+"]");
	}
}

运行Test类main方法:

(2)@After

After即为后置方法,在执行完目标方法后执行该方法。定义如下:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ComputerAOP {
	
	@Before("execution(public int com.jd.computer.service.ComputerService.*(..))")//扫描ComputerService类中的方法,与目标方法建立联系
	public void before(JoinPoint jp) {//JoinPoint 连接点对象
		Object [] args = jp.getArgs();//得到方法中传入的参数
		
		Signature signature = jp.getSignature();//得到切入点调用的的目标类的方法
		String name = signature.getName();//得到目标方法的名字
		System.out.println(this.getClass().getName()+":The "+name+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+name+":["+args[0]+","+args[1]+"]");
	}
	
	@After("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void after(JoinPoint jp) {
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println(this.getClass().getName()+":The "+name+" ends.");
	}
	
}

 运行Test类中的main方法:

(3)@AfterReturning 

AfterReturning 及执行完后置方法后用于返回结果的方法,但与之前不同的是,当有异常时,该方法不执行。定义如下:

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

@Aspect
@Component
public class ComputerAOP {
	
	@Before("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void before(JoinPoint jp) {//JoinPoint 连接点对象
		Object [] args = jp.getArgs();//得到方法中传入的参数
		
		Signature signature = jp.getSignature();//得到切入点调用的的目标类的方法
		String name = signature.getName();//得到目标方法的名字
		System.out.println(this.getClass().getName()+":The "+name+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+name+":["+args[0]+","+args[1]+"]");
	}
	
	@After("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void after(JoinPoint jp) {
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println(this.getClass().getName()+":The "+name+" ends.");
	}
	
	@AfterReturning(value = "execution(public int com.jd.computer.service.ComputerService.*(..))",returning = "result")
	public void afterReturning(JoinPoint jp,Object result) {
		System.out.println(this.getClass().getName()+":Result of the div method:"+result);
	}
}

运行Test类中main方法: 

(4)@AfterThrowing 

AfterThrowing 即为用于抛出异常的方法,与上个相反,有异常时才执行,无异常不执行。定义如下:

import org.aspectj.lang.JoinPoint;
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.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ComputerAOP {
	
	@Before("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void before(JoinPoint jp) {//JoinPoint 连接点对象
		Object [] args = jp.getArgs();//得到方法中传入的参数
		
		Signature signature = jp.getSignature();//得到切入点调用的的目标类的方法
		String name = signature.getName();//得到目标方法的名字
		System.out.println(this.getClass().getName()+":The "+name+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+name+":["+args[0]+","+args[1]+"]");
	}
	
	@After("execution(public int com.jd.computer.service.ComputerService.*(..))")
	public void after(JoinPoint jp) {
		Signature signature = jp.getSignature();
		String name = signature.getName();
		System.out.println(this.getClass().getName()+":The "+name+" ends.");
	}
	
	@AfterReturning(value = "execution(public int com.jd.computer.service.ComputerService.*(..))",returning = "result")
	public void afterReturning(JoinPoint jp,Object result) {
		System.out.println(this.getClass().getName()+":Result of the div method:"+result);
	}
	
	@AfterThrowing(value = "execution(public int com.jd.computer.service.ComputerService.*(..))",throwing = "e")
	public void afterThrowing(JoinPoint jp,Exception e) {
		System.out.println(e.getMessage());
	}
}

运行Test类中的main方法:(“0做分母”异常)

(5)@Around

Around可以同时前四个方法的整个过程,即开始,结束,返回结果,若有异常,不返回结果,返回异常。定义如下:

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

@Aspect
@Component
public class ComputerAOP {
	
	@Around(value="execution(public int com.jd.computer.service.ComputerService.*(..))")
	public Object around(ProceedingJoinPoint pjp) {
		Object[] args = pjp.getArgs();
		Signature signature = pjp.getSignature();
		String name = signature.getName();
		
		System.out.println(this.getClass().getName()+":The "+name+" begins.");
	    System.out.println(this.getClass().getName()+":Parameters of the "+name+":["+args[0]+","+args[1]+"]");
		
		try {
			Object result = null;
			try {
				//Object object = pjp.getTarget();//目标类创建对象
				//System.out.println("$$$$$$$$$$$"+object.getClass().getName());
				result = pjp.proceed();//调用目标方法,并返回目标方法的结果
			} finally {
				System.out.println(this.getClass().getName()+":The "+name+" ends.");
			}
			System.out.println(this.getClass().getName()+":Result of the div method:"+result);
			return result;
		} catch (Throwable e) {
			System.out.println(e.getMessage());
		}
		return -1;
	}
	
}

运行Test类(有异常时):

 运行Test类(无异常时):

标签:详述,getName,System,println,import,SpringAOP,org,public
来源: https://blog.csdn.net/Liuxiaoyang1999/article/details/104714361

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有