Spring简单入门(三)——面向切面编程aop

       首先介绍,什么是Aop,通俗来讲就是我们要对一个类的方法进行一些增强(例如在方法执行之前或者之后执行一些操作),我们不是采用修改源代码或者继承对方法再修改这种纵向抽取机制(要写大量重复代码),而是采用代理模式来增强。因此Aop就是使用代理实现的。

(1)基本概念的介绍

连接点JointPoint:被增强类里面的所有可用方法(这个概念基本没用)

切入点PointCut:类中需要被增强的方法。(重要概念,即连接点不一定是切入点,但是切入点一定是连接点)

通知Adviser:增强的方法,即需要切入点额外执行的方法(重要概念:分为前置(在切入点之前指向)、后置(切入点之后执行)、异常(切入点发生异常执行)、最终(在finally语句中执行)、环绕通知(切入点前后都有))

目标对象Target:被代理的对象,也就是要被增强的类

织入Weaving:把通知应用到目标对象来创建新的代理对象的过程

代理Proxy:产生的代理对象

切面Aspect:切入点与通知结合的过程(重要概念)

(2)基于XML的aop实现

首先引入约束和aop等jar包不提。首先要确定谁是目标对象,即被增强的类以及切入点,即被增强的方法。

public class Student {
	public void eat() {
		System.out.println("吃饭");
	}
}

例如当前例子,希望在eat()吃饭之前,能够进行“洗手”操作。则Student类就是目标对象,而eat()方法是切入点

既然要进行“洗手”操作,那么就要定义洗手操作:(因为方法不能单独存在,所以存在一个增强类中,washHand()就是通知

public class Adviser {
	public void washHand() {
		System.out.println("洗手");
	}
}

接下来才是配置的重点,也是Aop的难点。首先Student类和Adviser类都应该交给Spring来管理,即<bean>

使用<aop:config>标签进行配置,之后的标签都是其子标签。现在我们有了增强方法、有了目标类和切入点,那么就需要指定增强到底是在何时执行,即切面的配置。因此使用子标签<aop:aspect>进行配置。有两个属性,id是给这个切面起个id值,ref是重点,是增强方法所在类的id。(切入点表达式一般为:execution(* 包名.*.*(..))  )

接下来就需要指定到底是什么增强方式了,那就使用增强方式对应的子标签(例如前置增强对应<before>)属性method表示父标签中ref属性对应的增强类中的哪一个方法是增强方法。还有两个属性:pointcut是切入点表达式,但是这个切入点只能使用一次,因此,为了服用,会在<aop:config>下有一个子标签<aop:pointcut>第一个属性是expression,即切入点表达式,id属性为切入点id值。这样在<before>等标签中,可以使用pointcut-ref来使用该切入点。例子代码如下:

<bean id="Student" class="Test.Student"></bean>
<bean id="Adviser" class="Test.Adviser"></bean>
<aop:config>
	<aop:pointcut expression="execution(* Test.*.*(..))" id="pc1"/>
	<aop:aspect id="aspect" ref="Adviser">
		<aop:before method="washHand" pointcut-ref="pc1"/>
	</aop:aspect>	
</aop:config>

原理方面系统产生一个代理对象

Proxy proxy = ...;//通过代理获得代理对象
try {
	before();//前置通知
	proxy.doThing();//业务
	after();//后置通知
} catch (Exception e) {
	after_throwing();//异常通知
} finally {
	after_returning();//最终通知
}

再客户端,使用getBean()获得Student对象,然后调用其eat()方法,输出表示成功

洗手
吃饭

(3)基于注解的aop

在Aop方面,使用纯注解与使用XML+注解的区别不大。二者区别在于如何开启基于注解的Aop。

基于xml+注解:xml中使用<aop:aspectj-autoproxy/>来开启

基于纯注解:在配置类中使用@EnableAspectJAutoProxy来进行开启  

在增强类的增强方法上面添加@Aspect表面此类是增强类,建立切面。然后再增强方法上使用@Before("切入点表达式或者某一个方法名()") 。为了切入点复用,可以建立一个方法,上面使用@Pointcut("切入点表达式"),这样使用切入点表达式的地方都可以使用方法名()来代替

@Aspect
public class Adviser {
	@Before(value = "execution(* Test.*.*(..))")
	public void washHand() {
		System.out.println("洗手");
	}
}

或者

@Aspect
public class Adviser {
	@Pointcut(value = "execution(* Test.*.*(..))")
	public void m() {}
	@Before(value = "m()")
	public void washHand() {
		System.out.println("洗手");
	}
}

与xml配置aop相同,创建目标对象,然后调用其方法就可以实现aop操作了。

总结:了解Aop概念和相关术语,使用xml配置和注解完成aop操作

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值