最后输出(可以看出各种通知的时间):
我是前置通知。
我是环绕--进。
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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://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
@Aspect
public 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;
@Service
public class PersonMngImpl implements PersonMng {
@Override
public void delete(String id) {
System.out.println(id + " 已成功删除。");
}
@Override
public String get(int id) {
return "返回ID为 " + id + " 的人";
}
@Override
public void save(String name) {
//throw new RuntimeException("我是运行时异常。");
System.out.println(name + " 已成功保存");
}
}
测试:package com.mhm.spring.mng.impl;
import org.junit.AfterClass;
public class PersonMngImplTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Test
public void save() {
try{
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonMng personMng = (PersonMng)context.getBean("personMngImpl");
personMng.save("aa");
} catch (Exception e) {
e.printStackTrace();
}
}
@AfterClass
public 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
@Aspect
public 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;
}
}