代码结构及使用的jar
基于注解
MyInterceptor.java
package com.orange.test;
import org.aspectj.lang.ProceedingJoinPoint;
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 MyInterceptor {
/**
* execution:代表执行方法
* 第一个 * :所有返回类型
* com.orange.test.Service0 类
* 第二个 * :所有方法
* (..):方法参数,..指所有
*/
@Pointcut("execution(* com.orange.test.Service0.*(..))")
private void anyMonthod() {// 切入点
}
/**
* 方法执行之前执行
*/
@Before("anyMonthod()")
public void doBeforeCheck() {
System.out.println("前置通知");
}
/**
* 方法执行之后执行,如果异常则不执行
*/
@AfterReturning("anyMonthod()")
public void doAfterCheck() {
System.out.println("后置通知");
}
/**
* 方法执行之后执行,有无异常均执行
*/
@After("anyMonthod()")
public void doAfter() {
System.out.println("最终通知");
}
/**
* 方法出现异常时执行
*/
@AfterThrowing("anyMonthod()")
public void throwing() {
System.out.println("异常通知");
}
/**
* 环绕通知
* 只需要这个一个就可以执行上面所有的通知
*/
@Around("anyMonthod()")
public Object doBasicProfiling(ProceedingJoinPoint p) throws Throwable{
System.out.println("环绕通知开始.....");
Object result = p.proceed();
System.out.println("环绕通知结束.....");
return result;
}
}
Service0.java
package com.orange.test;
import org.springframework.stereotype.Service;
@Service
public class Service0 {
public void save(){
// throw new RuntimeException("异常。。。。。");
System.out.println("save方法。。。。");
}
public void update(){
System.out.println("update方法。。。。");
}
}
Test.java
package com.orange.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context1 = new ClassPathXmlApplicationContext("beans.xml");
Service0 service= (Service0)context1.getBean("service0");
service.save();
}
}
beans.xml
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd" >
<!-- 启用AOP -->
<aop:aspectj-autoproxy />
<!-- 对 com.orange.test 下的类扫描交给spring管理-->
<context:component-scan base-package="com.orange.test" />
</beans>
以上是通过注解的方式进行的AOP操作,接下来看一下基于配置文件的方式
修改一下MyInterceptor.java和beans.xml,另外两个类不需要改
MyInterceptor.java
package com.orange.test;
import org.aspectj.lang.ProceedingJoinPoint;
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 MyInterceptor {
/**
* execution:代表执行方法
* 第一个 * :所有返回类型
* com.orange.test.Service0 类
* 第二个 * :所有方法
* (..):方法参数,..指所有
*/
//@Pointcut("execution(* com.orange.test.Service0.*(..))")
private void anyMonthod() {// 切入点
}
/**
* 方法执行之前执行
*/
//@Before("anyMonthod()")
public void doBeforeCheck() {
System.out.println("前置通知");
}
/**
* 方法执行之后执行,如果异常则不执行
*/
//@AfterReturning("anyMonthod()")
public void doAfterCheck() {
System.out.println("后置通知");
}
/**
* 方法执行之后执行,有无异常均执行
*/
//@After("anyMonthod()")
public void doAfter() {
System.out.println("最终通知");
}
/**
* 方法出现异常时执行
*/
//@AfterThrowing("anyMonthod()")
public void throwing() {
System.out.println("异常通知");
}
/**
* 环绕通知
* 只需要这个一个就可以执行上面所有的通知
*/
//@Around("anyMonthod()")
public Object doBasicProfiling(ProceedingJoinPoint p) throws Throwable{
System.out.println("环绕通知开始.....");
Object result = p.proceed();
System.out.println("环绕通知结束.....");
return result;
}
}
beans.xml
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd" >
<!-- 启用AOP -->
<aop:aspectj-autoproxy />
<bean id="service0" class="com.orange.test.Service0"/>
<bean id="aopBean" class="com.orange.test.MyInterceptor"/>
<aop:config>
<aop:aspect id="aop" ref="aopBean">
<aop:pointcut id="myInterceptor" expression="execution(* com.orange.test.Service0.*(..))"/>
<!-- 前置通知 -->
<aop:before method="doBeforeCheck" pointcut-ref="myInterceptor"/>
<!-- 后置通知 -->
<aop:after-returning method="doAfterCheck" pointcut-ref="myInterceptor"/>
<!-- 最终通知-->
<aop:after method="doAfter" pointcut-ref="myInterceptor"/>
<!-- 异常通知-->
<aop:after-throwing method="throwing" pointcut-ref="myInterceptor"/>
<!-- 环绕通知-->
<aop:around method="doBasicProfiling" pointcut-ref="myInterceptor"/>
</aop:aspect>
</aop:config>
</beans>
注:基于注解的方式用jdk1.7执行的时候会包异常:Caused by: java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcut anyMonthod,原因是aspectjrt.jar和jdk1.7不兼容,所以换成了jdk1.6。