@AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格。通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的。
<aop:aspectj-autoproxy/>
如果需要使用该注解,需要包含一下几个包:
- aspectjrt.jar
- aspectjweaver.jar
- aspectj.jar
- aopalliance.jar
Aspects 类就和其他正常的bean一样,可以有方法和成员,除了该类是用@Aspect 注解的:
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
它们就和其他任何一个bean一样配置在XML中:
<bean id = "myAspect" class = "org.xyz.AspectModule">
bean>
声明一个切点:一个切点帮助决定使用不同的advices执行的感兴趣的点(比如方法)。当使用@AspectJ-based
配置的时候,切点声明有两部分。
下面的例子定义了一个名称为businessService
的切点,该切点匹配com.xyz.myapp.service
包中任意类的任意方法
import org.aspectj.lang.annotation.Pointcut;
@Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression
private void businessService() {} // signature
下面的例子定义了一个名称为getname
的切点,这个切点将匹配com.tutorialspoint
包中Student
类的getName()
方法。
import org.aspectj.lang.annotation.Pointcut;
@Pointcut("execution(* com.tutorialspoint.Student.getName(..))")
private void getname() {}
你可以使用@{ADVICE-NAME}
注解声明任何五种advices中的一种,这些都是在假定你已经定义了一个businessService()
切点声明前提下的。
@Before("businessService()")
public void doBeforeTask(){
...
}
@After("businessService()")
public void doAfterTask(){
...
}
@AfterReturning(pointcut = "businessService()", returning = "retVal")
public void doAfterReturnningTask(Object retVal) {
// you can intercept retVal here.
...
}
@AfterThrowing(pointcut = "businessService()", throwing = "ex")
public void doAfterThrowingTask(Exception ex) {
// you can intercept thrown exception here.
...
}
@Around("businessService()")
public void doAroundTask(){
...
}
你也可以在advices中定义一个切点,下面就是一个例子:
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}
Student.java
package com.soygrow.AspectJAnnotation;
public class Student {
private Integer age;
private String name;
public void setAge(Integer age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
System.out.println("Name : " + name);
return name;
}
public Integer getAge() {
System.out.println("Age : " + age);
return age;
}
public void printThrowException() {
System.out.println("Exception raised");
throw new IllegalArgumentException();
}
}
Logging.java
package com.soygrow.AspectJAnnotation;
import org.aspectj.lang.annotation.*;
@Aspect
public class Logging {
/**
* Following is the definition for a pointcut to select
* all the methods available. So advices will be called
* for all the methods.
*/
@Pointcut("execution(* com.soygrow.AspectJAnnotation.*.*(..))")
private void selectAll() {
}
/**
* This is the method which I would like to execute
* before a selected method execution.
*/
@Before("selectAll()")
public void beforeAdvice() {
System.out.println("Going to setup student profile.");
}
/**
* This is the method which I would like to execute
* after a selected method execution.
*/
@After("selectAll()")
public void afterAdvice() {
System.out.println("Student profile has been setup.");
}
/**
* This is the method which I would like to execute
* when any method returns.
*/
@AfterReturning(pointcut = "selectAll()", returning = "object")
public void afterReturningAdvice(Object object) {
System.out.println("Returning : " + object.toString());
}
/**
* This is the method which I would like to execute
* if there is an exception raised by any method.
*/
@AfterThrowing(pointcut = "selectAll()", throwing = "ex")
public void AfterThrowingAdvice(IllegalArgumentException ex) {
System.out.println("There has been an exception : " + ex.toString());
}
}
MainApp.java
package com.soygrow.AspectJAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("AspectJBeans.xml");
Student student = (Student) context.getBean("student");
student.getAge();
student.getName();
student.printThrowException();
}
}
AspectJBeans.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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<aop:aspectj-autoproxy/>
<bean id = "student" class = "com.soygrow.AspectJAnnotation.Student">
<property name = "name" value = "Zara" />
<property name = "age" value = "11"/>
bean>
<bean id = "logging" class = "com.soygrow.AspectJAnnotation.Logging"/>
beans>
如果一切正常,运行结果:
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning : 11
Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning : Zara
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception : java.lang.IllegalArgumentException
如果在XML配置文件中去掉
,那么就不会运行AspectJ相关代码
Exception in thread “main” org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘student’ defined in class path resource [AspectJBeans.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 can’t find referenced pointcut selectAll
at
问题是我用的AspectJ库文件的版本过低导致的,将版本从1.5.4升级到1.7.4就没有这个问题了