21.05.12
异常通知 @AfterThrowing
异常通知方法的定义格式
1.public
2.没有返回值
3.方法名称自定义
4.方法有一个Exception,如果还有时JoinPoint
@AfterThrowing
属性:1.value 切入点表达式
2.throwing 自定义的变量,表示目标方法抛出的异常对象,变量名必须和方法的参数名一样
特点:1.在目标方法抛出异常时执行的
2.可以做异常的监控程序,监控目标方法执行时是不是有异常
如果有异常,可以发送邮件,短信进行通知
执行就是:
try{
SomeServiceImpl.doSecond(…)
}catch(Exception e){
myAfterThrowing(e);
}
MyAspect.java
package com.node.ba04;
import com.sun.media.jfxmediaimpl.HostUtils;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@AfterThrowing(value = "execution(* *..SomeServiceImpl.doSecond(..))",
throwing = "ex")
public void myAfterThrowing(Exception ex){
System.out.println("异常通知:方法发生异常时,执行:"+ex.getMessage());
//发送邮件,短信,通知开发人员
}
}
测试代码
package com.node;
import com.node.ba04.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest04 {
@Test
public void test01(){
String config="applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(config);
//从容器中获取目标对象
SomeService proxy= (SomeService) ac.getBean("someService");
//通过代理的对象执行方法,事项目标方法执行时,增强了功能
proxy.doSecond();
}
}
最终通知 @After
最终通知方法的定义格式:
1.public
2.没有返回值
3.方法名称自定义
4.方法没有参数 ,如果有时JoinPoint
@After
属性:value 切入点表达式
位置:在方法的上面
特点:1.总是会执行
2.在目标方法之后执行
一般做资源清清除工作
try{
SomeServiceImpl.doThird(…)
}catch(Exception e){
}finally{
myAfter();
}
MyAspect.java
package com.node.ba05;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class MyAspect {
@After(value = "execution(* *..SomeServiceImpl.doThird(..))")
public void myAfter(){
System.out.println("执行最终通知,总是会执行的代码");
//一般做资源清除工作
}
}
测试代码
package com.node;
import com.node.ba05.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest05 {
@Test
public void test01(){
String config="applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(config);
//从容器中获取目标对象
SomeService proxy= (SomeService) ac.getBean("someService");
//通过代理的对象执行方法,事项目标方法执行时,增强了功能
proxy.doThird();
}
}
@Pointcut
@Pointcut
定义和管理切入点,如果项目中有多个切入点表达式是重复的,可以复用的,可以使用@Pointcut
属性:value 切入点表达式
位置:在自定义方法的上面
特点:当@Pointcut定义咋i一个方法的上面,此时这个方法的名称就是切入点表达式的别名。其他的通知中,value属性就可以使用这个方法名称,代替切入点表达式了
MyAspect.java
package com.node.ba06;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MyAspect {
@After(value = "mypt()")
public void myAfter(){
System.out.println("执行最终通知,总是会执行的代码");
//一般做资源清除工作
}
@Before(value="mypt()")
public void myBefore(){
System.out.println("执行前置通知");
}
@Pointcut(value = "execution(* *..SomeServiceImpl.doThird(..))")
public void mypt(){
//无需代码
}
}
目标类没有接口,使用cglib动态代理(默认)
目标类没有接口,使用cglib动态代理,spring框架会自动应用cglib
测试代码
package com.node;
import com.node.ba07.SomeServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest07 {
@Test
public void test01(){
String config="applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(config);
//从容器中获取目标对象
//目标类没有接口,使用cglib动态代理,spring框架会自定应用cglib
SomeServiceImpl proxy= (SomeServiceImpl) ac.getBean("someService");
//通过代理的对象执行方法,事项目标方法执行时,增强了功能
proxy.doThird();
}
}
目标类有接口,使用cglib动态代理
如果你期望目标类有接口,使用cglib
proxy-target-class=“true” : 告诉框架,要使用cglib动态代理
xml中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
AOP总结