Spring学习十六:使用Spring的注解方式实现AOP的细节
时间:2014-04-04 10:30:10
收藏:0
阅读:618
1、修改 MyInterceptor 类,代码如下:
package org.learn.spring.service; 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; @Aspect //声明切面 public class MyInterceptor { //定义要拦截的方法,拦截 personServiceImpl 类下所有方法的执行 /** * 第一个 * 表示 方法的返回值类型,* 表示任意类型 * org.learn.spring.service.impl.personServiceImpl 表示包下的类, 也可以写成 org.learn.spring.service 这样表示该包下所有的类,以及子包中的类 * 第二个 * 表示方法名称,这里表示是任意的方法,后接括号中的两点是表示参数是任意的,不管参数的个数和参数类型 */ @Pointcut("execution(* org.learn.spring.service.impl.personServiceImpl.*(..))") private void anyMethod() {}//声明一个切入点 @Before("anyMethod()")//定义前置通知 public void doAccessCheck() { System.out.println("前置通知"); } @AfterReturning("anyMethod()")//定义后置通知 public void doAfterReturning() { System.out.println("后置通知"); } @AfterThrowing("anyMethod()")//定义例外通知 public void doAfterThrowing() { System.out.println("例外通知"); } @After("anyMethod()")//定义最终通知 public void doAfter() { System.out.println("最终通知"); } @Around("anyMethod()")//定义环绕通知 public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法"); Object reuslt = pjp.proceed(); System.out.println("退出方法"); return reuslt; } }
如果要想执行例外通知,则要在调用的方法上抛出异常。如下代码所示:
package org.learn.spring.service.impl; import javax.management.RuntimeErrorException; import org.learn.spring.service.personService; public class personServiceImpl implements personService { @Override public void save(String name) { System.out.println("save()方法"); } @Override public void update(String name, Integer id) { //throw new RuntimeErrorException("例外通知"); System.out.println("update()方法"); } @Override public String getPersonServiceName(Integer id) { System.out.print("getPersonServiceName()方法"); return "xxx"; } }
将屏蔽的异常释放即可。
(2) 如果要想得到方法传入的参数值,即可如下:
args(name) 的 name 和 doAccessCheck(String name)参数名要一致 , 传入的参数类型是 String 类型,并且只有一个参数,由此也可以判断拦截的方法是哪一个
@Before("anyMethod() && args(name)")//定义前置通知 public void doAccessCheck(String name) { System.out.println("前置通知:"+name); }
(3) 获取方法的返回值,如下:
pointcut 切入点,returning 返回参数
@AfterReturning(pointcut="anyMethod()",returning="revalue")//定义后置通知 public void doAfterReturning(String revalue) { System.out.println("后置通知:"+revalue); }
(4) 得到方法抛出的异常,如下:
pointcut 切入点,throwing 抛出异常
@AfterThrowing(pointcut="anyMethod()", throwing="ex")//定义例外通知 public void doAfterThrowing(Exception ex) { System.out.println("例外通知:"+ex); }
(5) 详细如下:
package org.learn.spring.service; 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; @Aspect //声明切面 public class MyInterceptor { //定义要拦截的方法,拦截 personServiceImpl 类下所有方法的执行 /** * 第一个 * 表示 方法的返回值类型,* 表示任意类型 * org.learn.spring.service.impl.personServiceImpl 表示包下的类, 也可以写成 org.learn.spring.service 这样表示该包下所有的类,以及子包中的类 * 第二个 * 表示方法名称,这里表示是任意的方法,后接括号中的两点是表示参数是任意的,不管参数的个数和参数类型 */ @Pointcut("execution(* org.learn.spring.service.impl.personServiceImpl.*(..))") private void anyMethod() {}//声明一个切入点 //传入的参数类型是 String 类型,并且只有一个参数,由此也可以判断拦截的方法是哪一个 //args(name) 的 name 和 doAccessCheck(String name)参数名要一致 @Before("anyMethod() && args(name)")//定义前置通知 public void doAccessCheck(String name) { System.out.println("前置通知:"+name); } // pointcut 切入点,returning 返回参数 @AfterReturning(pointcut="anyMethod()",returning="revalue")//定义后置通知 public void doAfterReturning(String revalue) { System.out.println("后置通知:"+revalue); } // pointcut 切入点,throwing 抛出异常 @AfterThrowing(pointcut="anyMethod()", throwing="ex")//定义例外通知 public void doAfterThrowing(Exception ex) { System.out.println("例外通知:"+ex); } @After("anyMethod()")//定义最终通知 public void doAfter() { System.out.println("最终通知"); } @Around("anyMethod()")//定义环绕通知 public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable { System.out.println("进入方法"); Object reuslt = pjp.proceed(); System.out.println("退出方法"); return reuslt; } }
(6) 要得到想要的结果,测试类中调用的方法也在改变:
package org.learn.spring.test; import org.junit.Test; import org.learn.spring.service.personService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class personTest { @Test public void test() { //实例化spring容器 ApplicationContext cxt = new ClassPathXmlApplicationContext("learn1.xml"); personService service = (personService)cxt.getBean("personService"); service.save("xxx"); service.getPersonServiceName(1); service.update("dddd", 3); } }
(7) personServiceImpl 类中的 update 方法要做改变:
@Override public void update(String name, Integer id) { throw new RuntimeException("例外通知"); //System.out.println("update()方法"); }
Spring学习十六:使用Spring的注解方式实现AOP的细节,布布扣,bubuko.com
原文:http://www.cnblogs.com/hwlsniper/p/3644241.html
评论(0)