Spring使用AspectJ的面向切面AOP的通知

版权声明:本文为博主原创文章,未经博主允许不得转载。 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/>

猜你喜欢

转载自blog.csdn.net/wangyang668/article/details/82779412
今日推荐