Spring 专题
专题目录
您的位置:java > Spring专题 > Spring AOP+AspectJ注解实例
Spring AOP+AspectJ注解实例
作者:--    发布时间:2019-11-20
在本教程中,我们将向你展示如何将aspectj注解集成到spring aop框架。在这个spring aop+ aspectj 示例中,让您轻松实现拦截方法。
常见aspectj的注解:
  1. @before – 方法执行前运行
  2. @after – 运行在方法返回结果后
  3. @afterreturning – 运行在方法返回一个结果后,在拦截器返回结果。
  4. @afterthrowing – 运行方法在抛出异常后,
  5. @around – 围绕方法执行运行,结合以上这三个通知。
注意
spring aop 中没有 aspectj 支持,请阅读 内置 spring aop 例子

1. 目录结构

看到这个例子的目录结构。

2. spring beans

普通 bean 中有几个方法,后来通过 aspectj 注解拦截。
package com.h3.customer.bo;

public interface customerbo {

	void addcustomer();
	
	string addcustomerreturnvalue();
	
	void addcustomerthrowexception() throws exception;
	
	void addcustomeraround(string name);
}
package com.h3.customer.bo.impl;

import com.h3.customer.bo.customerbo;

public class customerboimpl implements customerbo {

	public void addcustomer(){
		system.out.println("addcustomer() is running ");
	}
	
	public string addcustomerreturnvalue(){
		system.out.println("addcustomerreturnvalue() is running ");
		return "abc";
	}
	
	public void addcustomerthrowexception() throws exception {
		system.out.println("addcustomerthrowexception() is running ");
		throw new exception("generic error");
	}
	
	public void addcustomeraround(string name){
		system.out.println("addcustomeraround() is running, args : " + name);
	}
}

4. 启用aspectj

在 spring 配置文件,把“<aop:aspectj-autoproxy />”,并定义aspect(拦截)和普通的bean。

file : applicationcontext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemalocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/aop 
	http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

	<aop:aspectj-autoproxy />

	<bean id="customerbo" class="com.h3.customer.bo.impl.customerboimpl" />

	<!-- aspect -->
	<bean id="logaspect" class="com.h3.aspect.loggingaspect" />

</beans>

4. aspectj @before

在下面例子中,logbefore()方法将在 customerbo接口的 addcustomer()方法的执行之前被执行。
aspectj的“切入点”是用来声明哪种方法将被拦截,应该参考spring aop切入点指南,支持切入点表达式的完整列表。

file : loggingaspect.java

package com.h3.aspect;

import org.aspectj.lang.joinh3;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.before;

@aspect
public class loggingaspect {

	@before("execution(* com.h3.customer.bo.customerbo.addcustomer(..))")
	public void logbefore(joinh3 joinh3) {

		system.out.println("logbefore() is running!");
		system.out.println("hijacked : " + joinh3.getsignature().getname());
		system.out.println("******");
	}

}

运行

customerbo customer = (customerbo) appcontext.getbean("customerbo");
customer.addcustomer();

输出结果

logbefore() is running!
hijacked : addcustomer
******
addcustomer() is running

5. aspectj @after

在下面例子中,logafter()方法将在 customerbo 接口的 addcustomer()方法的执行之后执行。

file : loggingaspect.java

package com.h3.aspect;

import org.aspectj.lang.joinh3;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.after;

@aspect
public class loggingaspect {

	@after("execution(* com.h3.customer.bo.customerbo.addcustomer(..))")
	public void logafter(joinh3 joinh3) {

		system.out.println("logafter() is running!");
		system.out.println("hijacked : " + joinh3.getsignature().getname());
		system.out.println("******");

	}

}

运行它

customerbo customer = (customerbo) appcontext.getbean("customerbo");
customer.addcustomer();

输出结果

addcustomer() is running 
logafter() is running!
hijacked : addcustomer
******

6. aspectj @afterreturning

在下面例子中,logafterreturning()方法将在 customerbo 接口的addcustomerreturnvalue()方法执行之后执行。此外,还可以截取返回的值使用“returning”属性。

要截取返回的值,对“returning”属性(结果)的值必须用相同的方法参数(结果)。

file : loggingaspect.java

package com.h3.aspect;

import org.aspectj.lang.joinh3;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.afterreturning;

@aspect
public class loggingaspect {

   @afterreturning(
      pointcut = "execution(* com.h3.customer.bo.customerbo.addcustomerreturnvalue(..))",
      returning= "result")
   public void logafterreturning(joinh3 joinh3, object result) {

	system.out.println("logafterreturning() is running!");
	system.out.println("hijacked : " + joinh3.getsignature().getname());
	system.out.println("method returned value is : " + result);
	system.out.println("******");
   }
}

运行它

customerbo customer = (customerbo) appcontext.getbean("customerbo");
	customer.addcustomerreturnvalue();

输出结果

addcustomerreturnvalue() is running 
logafterreturning() is running!
hijacked : addcustomerreturnvalue
method returned value is : abc
******

7. aspectj @afterreturning

在下面的例子中,如果 customerbo 接口的addcustomerthrowexception()方法抛出异常logafterthrowing()方法将被执行。

file : loggingaspect.java

package com.h3.aspect;

import org.aspectj.lang.joinh3;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.afterthrowing;

@aspect
public class loggingaspect {

   @afterthrowing(
      pointcut = "execution(* com.h3.customer.bo.customerbo.addcustomerthrowexception(..))",
      throwing= "error")
    public void logafterthrowing(joinh3 joinh3, throwable error) {

	system.out.println("logafterthrowing() is running!");
	system.out.println("hijacked : " + joinh3.getsignature().getname());
	system.out.println("exception : " + error);
	system.out.println("******");

    }
}

运行它

customerbo customer = (customerbo) appcontext.getbean("customerbo");
customer.addcustomerthrowexception();

输出结果

addcustomerthrowexception() is running 
logafterthrowing() is running!
hijacked : addcustomerthrowexception
exception : java.lang.exception: generic error
******
exception in thread "main" java.lang.exception: generic error
	//...

8. aspectj @around

在下面例子中,logaround()方法将在customerbo接口的addcustomeraround()方法执行之前执行, 必须定义“joinh3.proceed();” 控制何时拦截器返回控制到原来的addcustomeraround()方法。

file : loggingaspect.java

package com.h3.aspect;

import org.aspectj.lang.proceedingjoinh3;
import org.aspectj.lang.annotation.aspect;
import org.aspectj.lang.annotation.around;

@aspect
public class loggingaspect {

   @around("execution(* com.h3.customer.bo.customerbo.addcustomeraround(..))")
   public void logaround(proceedingjoinh3 joinh3) throws throwable {

	system.out.println("logaround() is running!");
	system.out.println("hijacked method : " + joinh3.getsignature().getname());
	system.out.println("hijacked arguments : " + arrays.tostring(joinh3.getargs()));
		
	system.out.println("around before is running!");
	joinh3.proceed(); //continue on the intercepted method
	system.out.println("around after is running!");
		
	system.out.println("******");

   }
	
}

运行它

customerbo customer = (customerbo) appcontext.getbean("customerbo");
customer.addcustomeraround("h3");

输出结果

logaround() is running!
hijacked method : addcustomeraround
hijacked arguments : [h3]
around before is running!
addcustomeraround() is running, args : h3
around after is running!
******

总结

它总是建议采用最少 aspectj 注解。这是关于spring aspectj 的一篇相当长的文章。进一步的解释和例子,请访问下面的参考链接。

下载源代码 – http://pan.baidu.com/s/1boo4f9p

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册