Spring 中 AOP 思想实例解析

AOP 面向切面编程,和IOC 控制反转是 Spring 框架的两个重要思想。

AOP以自己的话来说,以一个对象的某个方法为切点,在这个切点的前后加上一些增强功能,使得该整体具有更多的功能。

 

看以下代码的例子

原本我是直接回家(目标:gohome)就这么一件事,但是事情并不那么简单,以我要回家这个点,前前后后都发生了事情。

所发生的事(advice)作为一个切面切入到我要回家的这件事中。于是,我在回家之前得做什么,回家之后得做什么,都在切面安排好了。

还可以以切面中的某个点切入其他事情,如果事情太多,还可以有多个切面同时切入一个点。当然一个整体可以有多个切点。切面中的功能可以切入到切点的前面或后面。

package com.springAOP;

public class Gohome {
	public Gohome() {
		
	}
	
	public String goHome() {
		
		System.out.println("开开心心回家咯-----(目标对象)");
	//	int i = 1 / 0; //制造一个异常
		
		return "吃饱喝足后去散散步吧";
	}
}

定义一个切面

package com.springAOP;

import org.aspectj.lang.ProceedingJoinPoint;

public class Advice {
	//出现异常后调用的通知
	public void afterException() {
		System.out.println("突发事件:被老板叫住,需要处理完额外的任务才能走!!!!!!!(出现异常调用的通知)");
	}

	//前置通知
	public void work() {
		System.out.println("不知不觉到了下班时间,收拾好准备回家吧。。(前置通知)");
	}
	
	//环绕通知
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("回家前,整理邮件(环绕通知前)");
		Object proceed = pjp.proceed();
		System.out.println("回家后,整理邮件(环绕通知后)");
		return proceed;
	}
	
	//后置通知(出现异常也会调用)
	public void cookie() {
		System.out.println("今天就做辣椒炒肉做晚餐吧(后置通知:出现异常也会调用)");
	}
	
	//后置通知(出现异常不用调用)
	public void afterReturning(Object value) {
		System.out.println(value + "(后置通知:出现异常不会调用)");
	}
}

把这个切面切入到目标对象中(配置文件 applicationContext.xml)需要导入 aop 约束

配置切入点时,第一个 * 号表示任意访问修饰符,一般为 public ,该 * 可以省略

第二个 * 号表示返回值任意,方法名也可以写成 * 号,表示其中的所有方法都要执行配置的通知。

括号中的两个点表示参数任意,可有可无

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xmlns="http://www.springframework.org/schema/beans" 
		xmlns:aop="http://www.springframework.org/schema/aop" 
		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 ">

	<!-- 配置目标对象 -->
	<bean name="gohome" class="com.springAOP.Gohome"></bean>
	
	<!-- 配置通知对象 -->
	<bean name="advice" class="com.springAOP.Advice"></bean>

	<!-- 配置将通知织入目标对象 -->
	<aop:config>
		<!-- 配置切入点 -->
		<aop:pointcut expression="execution(* *com.springAOP.Gohome.goHome(..))" id="pc"/>
		
		<!-- 配置切面 -->
		<aop:aspect id="aspect" ref="advice">
		
		<!-- 异常通知 -->
		<aop:after-throwing method="afterException" pointcut-ref="pc"/>
		
		<!-- 前置通知 -->
		<aop:before method="work" pointcut-ref="pc"/>
		
		<!-- 环绕通知 -->
		<aop:around method="around" pointcut-ref="pc"/>
		
		<!-- 后置通知 (出现异常也会通知)-->
		<aop:after method="cookie" pointcut-ref="pc"/>
		
		<!-- 后置通知 (出现异常不会通知)   returning 用来接收目标对象的返回值(无返回值则不接收)-->
		<aop:after-returning method="afterReturning" pointcut-ref="pc" returning="value"/>
		
		</aop:aspect>
	</aop:config>


</beans>

执行目标对象的动作

package com.springAOP;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class Test {
	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		
		Gohome gh = (Gohome) ac.getBean("gohome");
		
		gh.goHome();
		
	}
}

执行结果:


本来我执行的 goHome,但是 advice 中的各个方法也都执行了,说明那些方法确实切进来了。


以上是以个人理解举的例子,仅供参考!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值