代码结构及使用的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。