Spring AOP annotation 简单实例
最后输出(可以看出各种通知的时间):
?
我是前置通知。
我是环绕--进。
aa 已成功保存
我是后置通知。
我是最终通知。
我是环绕--出。
?
app.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:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><aop:aspectj-autoproxy /><context:component-scan base-package="com.mhm.spring"/></beans>
?
MyAOP.Java
package com.mhm.spring.mng.impl;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;@Component@Aspectpublic class MyAOP {//声明切入点 //注意,impl下面的类必须实现了mng中的接口,不然不能实现代理,但如果还是要使用代理 //那么,在项目中加入cglib,它会根据二进制来实现代理@Pointcut("execution(* com.mhm.spring.mng.impl..*.*(..))")public void anyMethod(){};//前置通知@Before("anyMethod()")public void dobefore() {System.out.println("我是前置通知。");}//后置通知@AfterReturning("anyMethod()")public void doafterReturning() {System.out.println("我是后置通知。");}//最终置通知@After("anyMethod()")public void doafter() {System.out.println("我是最终通知。");}//异常通知@AfterThrowing("anyMethod()")public void doexception() {System.out.println("我是异常通知。");}//环绕通知@Around("anyMethod()")public Object doprocess(ProceedingJoinPoint pjp) throws Throwable {System.out.println("我是环绕--进。");Object o = pjp.proceed();System.out.println("我是环绕--出。");return o;}}?
PersonMng.java
package com.mhm.spring.mng;public interface PersonMng {public void save(String name);public String get(int id);public void delete(String id);}?
PersonMngImpl:
package com.mhm.spring.mng.impl;import org.springframework.stereotype.Service;@Servicepublic class PersonMngImpl implements PersonMng {@Overridepublic void delete(String id) {System.out.println(id + " 已成功删除。");}@Overridepublic String get(int id) {return "返回ID为 " + id + " 的人";}@Overridepublic void save(String name) {//throw new RuntimeException("我是运行时异常。");System.out.println(name + " 已成功保存");}}?
测试:package com.mhm.spring.mng.impl;
import org.junit.AfterClass;public class PersonMngImplTest {@BeforeClasspublic static void setUpBeforeClass() throws Exception {}@Testpublic void save() {try{ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");PersonMng personMng = (PersonMng)context.getBean("personMngImpl");personMng.save("aa");} catch (Exception e) {e.printStackTrace();}}@AfterClasspublic static void tearDownAfterClass() throws Exception {}}?
//下面是稍微复杂点的MyAOP
package com.mhm.spring.mng.impl;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;@Component@Aspectpublic class MyAOP {//声明切入点@Pointcut("execution(* com.mhm.spring.mng.impl..*.*(..))")public void anyMethod(){};//前置通知//拦截参数为String类型的方法@Before("anyMethod() && args(name)")public void dobefore(String name) {System.out.println("我是前置通知。" + name);}//后置通知//拦截 返回类型为String 的方法@AfterReturning(pointcut="anyMethod()", returning="result")public void doafterReturning(String result) {System.out.println("result: " + result);System.out.println("我是后置通知。" );}//最终置通知@After("anyMethod()")public void doafter() {System.out.println("我是最终通知。");}//异常通知@AfterThrowing(pointcut="anyMethod()", throwing="ex")public void doexception(Exception ex) {System.out.println("我是异常通知: " + ex);}//环绕通知@Around("anyMethod()")public Object doprocess(ProceedingJoinPoint pjp) throws Throwable {System.out.println("我是环绕--进。");Object o = pjp.proceed();System.out.println("我是环绕--出。");return o;}}??
?
?
?