carioo的专栏

AOP是AspcetOrientedProgramming,实质意思就是将一些横切逻辑结成模块然后插入到业务逻辑的周围,而不侵入业务逻辑的代码当中,现在我们来看看aop的一些术语:

(1)连接点(JoinPoint):Spring只支持方法连接点,在spring中,方法都可以作为连接点

(2)切点(Pointcut):具体执行业务逻辑的业务方法所在处,可以通过切点函数得到具体的切点

(3)增强(Advice):织入到目标类连接点上的一段代码,并且拥有方位信息(方位指的是在切点的前面还是后面的意思)

(4)目标对象(target):增强织入的目标对象

(5)引介(introduction):为类增加一些接口和属性

(6)织入(weaving):spring采用动态代理,在运行期织入增强

(7)代理(Proxy):融合了原类和增强产生的结果类

(8):切面(Aspect):切面由切点和增强组成,Spring就是实现将增强添加到切点所在的位置

之前说道beanPostProcessor对于实现aop起到了重要作用,这里我们可以看到,这是因为这个processor提供了一些可以自动代理创建器,帮助增强织入到目标对象中产生代理对象

好了,现在我们继续来看下,spring有4种定义切面的方式:

一.基于Advisor类的方式:增强必须实现对应的接口,内部使用一个proxyFactory来产生代理对象(由于使用的较少,所以在这里不给demo)

二.基于注解:

@Aspectpublic class TestAspect {@Before("execution(* say(..))")public void say(){System.out.println("hi");}}<aop:aspectj-autoproxy/><bean id="carTarget" class="com.yue.test.PrivateCar"/><bean id="testAspect" class="com.yue.aspectj.TestAspect"/>String path = "bao.xml";ApplicationContext ac = new ClassPathXmlApplicationContext(path);PrivateCar pc = (PrivateCar) ac.getBean("carTarget");pc.say();因为在这里当你通过getBean得到的已经是代理对象,所以在使用say方法的时候,实质上是调用了代理对象的这个方法。

下面来看看切点函数:

下面来介绍三个常用的切点函数:execution(),within(),target()

(1):execution(* *To(..))

第一个*代表任意返回值的方法,第一个*到括号之前代表方法的名字,*号代表任意数目的字符,这里是一切以to为后缀的方法,..表示任意多个参数

(2)within(com.baobaotao.*)匹配baobaotao这个包中所有类中的所有方法(不包括子类)

within(com.baobaotao..*)匹配所有类所有方法包括子类

(3)target(com.baobaotao.waiter)所有这个类和其子类的所有方法都匹配

然后再继续看看切点函数的复合运算:

&&:表示要取两个范围的交集

||:表示要取两个范围的并集

!:表示要取两个范围的非集

命名切点:使切点可以重用

不过这里有一个bug,照理说当方法修饰符是public的时候其他包中的切面应该也是可以引用这个切点的,然而在实验中会出现errorbindtype的错误,这令人十分不解,望高手指教

demo:

@Before("Gg.talk()")public void say(){System.out.println("hi");}public class Gg {/* * 必须注意的是方法修饰符限定了这个切点的使用范围 */@Pointcut("execution(* say(..))")public void talk(){}}还有特殊一点的环绕增强,可以用过一个proceedingJoinPoint对象访问连接点的信息

@Aspectpublic class TestAspect {/* * 值得注意的是在环绕增强中,必须显示的调用pjp.proceed()方法调用业务逻辑 */@Around("Gg.talk()")public void say(ProceedingJoinPoint pjp) throws Throwable{System.out.println("fdaf");pjp.proceed();System.out.println("what a spring!");}}三.基于schema定义切面(这也是我觉得最有美感的一种)

直接上demo:

<aop:config proxy-target-class="true"><aop:pointcut expression="execution(* *say(..))" id="point"/><aop:aspect ref="greetingAdvice"><aop:before pointcut-ref="point" method="says"/></aop:aspect></aop:config><bean id="greetingAdvice" class="com.yue.test.GreetingBeforeAdvice" /><bean id="carTarget" class="com.yue.test.PrivateCar"/><aop:config>表示在这里面定义的切面会自动织入目标对象产生代理对象,proxy-target-class表示使用jdk代理还是cglib代理

<aop:aspect>表示定义一个切面,ref表示这个切面引用的增强bean对象,,里面的method表示织入这个增强bean中的哪个方法

<aop:pointcut>表示定义一个切点,切面可以使用pointcut-ref引用这个切点

注意的是当时环绕增强的时候,对应的方法要改为:

public void says(ProceedingJoinPoint pjp) throws Throwable{System.out.println("ggg");pjp.proceed();

一错再错,把握正确的方向,

carioo的专栏

相关文章:

你感兴趣的文章:

标签云: