版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wangyang668/article/details/82779412
1.通知
五种通知:前置通知 、后置通知、 环绕通知、异常通知 、最终通知 。
2.通知基于XML的实现
自定义切面类MyAspect:
//前置通知
public void before() {
System.out.println("前置通知方法");
}
//后置通知 :改变不了结果值
public void afterReturning() {
System.out.println("后置通知方法");
}
//环绕通知
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知方法,目标方法执行之前");
//执行目标方法
Object result = pjp.proceed();
System.out.println("环绕通知方法,目标方法执行之后");
return ((String)result).toUpperCase();
}
//异常通知
public void AfterThrowing(Exception ex) {
System.out.println("异常通知方法 ex = " + ex.getMessage());
}
//最终通知:无论是否抛出异常都会执行
public void after() {
System.out.println("最终通知方法");
}
SomeServiceImpl实现ISomeService接口:
@Override
public void doFirst() {
System.out.println("执行主业务逻辑doFirst()");
}
@Override
public String doSecond() {
System.out.println("执行主业务逻辑doSecond()");
return "abcde";
}
@Override
public void doThird() {
//System.out.println("执行主业务逻辑doThird()");
System.out.println("执行主业务逻辑doThird() 。。。" + 3/0);
}
applicationContext.xml配置文件:
<!-- 注册目标对象 -->
<bean id="someService" class="com.aop_xml.SomeServiceImpl"></bean>
<!-- 注册切面 -->
<bean id="MyAspect" class="com.aop_xml.MyAspect"></bean>
<!-- aop配置-->
<aop:config>
<aop:pointcut expression="execution(* *..ISomeService.doFirst(..))" id="doFirstPointcut"/>
<aop:pointcut expression="execution(* *..ISomeService.doSecond(..))" id="doSecondPointcut"/>
<aop:pointcut expression="execution(* *..ISomeService.doThird(..))" id="doThirdPointcut"/>
<aop:aspect ref="MyAspect">
<!--前置通知 -->
<aop:before method="before" pointcut-ref="doFirstPointcut"/>
<aop:before method="before(org.aspectj.lang.JoinPoint)" pointcut-ref="doFirstPointcut"/>
<!--后置通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="doSecondPointcut"/>
<aop:after-returning method="afterReturning(java.lang.String)" pointcut-ref="doSecondPointcut" returning="result"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="doSecondPointcut"/>
<!-- 异常通知 -->
<aop:after-throwing method="AfterThrowing" pointcut-ref="doThirdPointcut" throwing="ex"/>
<!-- 最终通知 -->
<aop:after method="after" pointcut-ref="doThirdPointcut"/>
</aop:aspect>
</aop:config>
测试类:
@Test
public void test01() {
//加载Spring配置文件,创建Spring容器对象
String resource = "com/aop_xml/applicationContext.xml";
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(resource);
//从容器中获取指定Bean对象
ISomeService service = (ISomeService) ac.getBean("someService");
service.doFirst();
System.out.println("-------------------");
String result = service.doSecond();
System.out.println(result);
System.out.println("-------------------");
service.doThird();
}
3.通知基于注解的实现
ISomeService与其实现类SomeServiceImpl和测试类与基于xml的一样,这里就不再写了。
自定义切面类:
@Aspect //表示当前类为切面
public class MyAspect {
//前置通知
@Before("execution(* *..ISomeService.doFirst(..))")
public void before() {
System.out.println("前置通知方法");
}
//后置通知 :改变不了结果值
@AfterReturning("execution(* *..ISomeService.doSecond(..))")
public void afterReturning() {
System.out.println("后置通知方法");
}
//环绕通知
@Around("execution(* *..ISomeService.doSecond(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知方法,目标方法执行之前");
//执行目标方法
Object result = pjp.proceed();
System.out.println("环绕通知方法,目标方法执行之后");
return ((String)result).toUpperCase();
}
//异常通知
@AfterThrowing(value="doThirdPointcut()",throwing="ex")
public void AfterThrowing(Exception ex) {
System.out.println("异常通知方法 ex = " + ex.getMessage());
}
//最终通知:无论是否抛出异常都会执行
@After("doThirdPointcut()")
public void after() {
System.out.println("最终通知方法");
}
//定义切入点
@Pointcut("execution(* *..ISomeService.doThird(..))")
private void doThirdPointcut() {}
applicationContext.xml配置文件:
<!-- 注册目标对象 -->
<bean id="someService" class="com.aop_annotation.SomeServiceImpl"></bean>
<!-- 注册切面 -->
<bean id="myAdvice" class="com.aop_annotation.MyAspect"></bean>
<!-- 生成代理对象-->
<aop:aspectj-autoproxy/>