ICode9

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

详述Spring AOP中的@Before,@After,@AfterReturning,@AfterThrowing和@Around

2020-03-05 21:03:53  阅读:453  来源: 互联网

标签:Around int Spring getName After System name public out


AOP的定义:AOP将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。

 

简单来说,就是将多个对象中的,非核心重复性高的代码单独封装,以供调用。

极大地提高了代码复用率,降低了模块耦合度。

 

以下为其实现的一个简例。

@Service
public class ComputerService implements IComputerService {

    public int add(int a, int b) {
        advice("add", a, b); 
        return a+b;
    }
    public int div(int a, int b) {
    advice("div", a, b);
    return a/b;
    }

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

可以看出在ComputerService中advice内代码需被int与div调用,而advice中代码也可能被其他方法调用,于是将其抽出,形成一个单独的AOP。

AOP中有以下五个重要注释,它们决定了复用代码出现在目标方法的哪个位置。

  • @Before
  • @After
  • @AfterReturning
  • @AfterThrowing
  • @Around

在使用这些注释前需配置xml文件

<!--自动代理 自动给匹配execution表达式目标类生产代理类并创造代理对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--对应@Aspect注释-->
public class ComputerService implements IComputerService {

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

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

}

更改ComputerService内代码


1.@Before(目标方法执行之前)

在advice中内容是int,div调用之前输出的,因而用到了@Before

创建新的java类ComputerAop,并添加@Aspect与@Component注释。

public class ComputerAop{
	
	//目标方法执行之前
	@Before("execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))")
    //xxx ComputerService前的路径。它会自动寻找ComputerService中所有public int的方法。
	public void before(JoinPoint jp) {
		Object[] args=jp.getArgs();
    //获取目标方法对应参数
		Signature sg=jp.getSignature();
    //获取目标方法
		String name=sg.getName();
		System.out.println(this.getClass().getName()+":the "+name+" method begins.");
		System.out.println(this.getClass().getName()+":parameters of the "+name+" method["+args[0]+","+args[1]+"].");
	}
}

执行结果如下


2.@After(目标方法执行完,无论是否出现错误异常,都会执行)

@After("execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))")
	public void after(JoinPoint jp){
		Signature sg=jp.getSignature();
		String name=sg.getName();
		System.out.println(this.getClass().getName()+":The "+name+"method ends");
	}

执行结果如下


3.@AfterReturning(目标方法返回结果时,出现错误异常,不会执行)

@AfterReturning(value="("execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))")",returning="result")
	public void afterReturning(JoinPoint jp,Object result) {
		Signature sg=jp.getSignature();
		String name=sg.getName();
		System.out.println(this.getClass().getName()+"the result of :"+name+" is "+result);
	}

当div方法传参数(1,1)时,return结果无措,正常执行。

当div方法传参数(1,0)时,return结果有措,不执行。


4.@AfterThrowing(目标方法出现错误异常执行)

@AfterThrowing(value="execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))",throwing="e")
	public void afterThrowing(JoinPoint jp,Exception e) {
		System.out.println(e.getMessage());
	}

结果如下,打印出了错误。


5.@Around(可以实现以上所有功能)

@Around(value = "execution(public int xxx.xx.xxxxx.xxxxx.ComputerService.*(..))")
public object around(ProceedingJoinPoint pjp) {
    object [] args = pjp.getArgs();//传入目标方法的参数
    signature sg = pjp.getSignature();
    String name = sg.getName();
    System.out .print1n( this. getClass().getName()+": The "+name+" method begins.");
    System.out.println(this.getClass().getName()+": Parameters of the "+name+" method: [" +args[0]+"," +args[1]+"]");
try {
    try {
        object object = pjip. getTarget();//目标类创建的对象
        System.out.print1n("*******" +object. getClass() . getName());
        object result =pjp. proceed();//调用目标方法,并且返回目标方法的结果
        System.out.println(this.getClass() .getName()+": Result of the "+name+" method: " +result);
        return result;
}finally {
    System.out.println(this.getClass().getName()+": The "+name+" method ends.");
} catch (Throwable e) {
    System.out.println(e.getMessage();|
    return -1;
}

 

标签:Around,int,Spring,getName,After,System,name,public,out
来源: https://blog.csdn.net/nairuozi/article/details/104678690

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

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

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

ICode9版权所有