[url=/blog/2111957]书接上回[/url]
上回说道LEO盗梦,宿主抛出了Exception,LEO早有应对,逃脱了。
LEO审视自己的类,发现所有的盗梦行为中,都需要在睡梦之前做准备@before,梦醒之后逃脱@after。那么是不是可以把这两个方法合一呢。
这里我们用到@Around,这个代码貌似应该这么写
伪代码
我们知道在编织waving的时候,我们用了@before和@after来表示方法在宿主运行之前还是之后。使用Spring是没有显式调用的,也就是说我们不能直接调用业务方法。这里我们用到的是ProceedingJoinPoint。
这里稍微先说说JointPoint,我不习惯大段列举名词的介绍方法,我们的原则是用到什么讲什么。
JointPoint意思是连接点,就是业务代码和Aspect代码的交汇点。在电影里,就是你做你的梦,LEO跑到你的梦里的特定方法中。一般来说连接点主要是只宿主的方法。
剩下的就好办了,ProceedingJointPoint就是指被切面切入的方法。
这里直接上代码
1、LEOIncept
与before和after不同的是,首先我要声明一个pointcut叫做myPointcut方法,myPointcut()方法里面是不需要写代码的,写了也不会执行,Spring只是用到了myPointcut()方法的方法名而已。之后的@Around是利用了myPointcut()的名字,表示切入点@Pointcut("execution(public void com.spring.service.Person.haveSleep())")这里。
pjp.proceed()是用于表示业务代码,在这里就是haveSleep()方法。
2、修改Person方法
3、测试代码
测试结果
上回说道LEO盗梦,宿主抛出了Exception,LEO早有应对,逃脱了。
LEO审视自己的类,发现所有的盗梦行为中,都需要在睡梦之前做准备@before,梦醒之后逃脱@after。那么是不是可以把这两个方法合一呢。
这里我们用到@Around,这个代码貌似应该这么写
伪代码
before应该做的事情
宿主的业务
after应该做的事情
我们知道在编织waving的时候,我们用了@before和@after来表示方法在宿主运行之前还是之后。使用Spring是没有显式调用的,也就是说我们不能直接调用业务方法。这里我们用到的是ProceedingJoinPoint。
这里稍微先说说JointPoint,我不习惯大段列举名词的介绍方法,我们的原则是用到什么讲什么。
JointPoint意思是连接点,就是业务代码和Aspect代码的交汇点。在电影里,就是你做你的梦,LEO跑到你的梦里的特定方法中。一般来说连接点主要是只宿主的方法。
剩下的就好办了,ProceedingJointPoint就是指被切面切入的方法。
这里直接上代码
1、LEOIncept
package com.spring.aop;
import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LeoIncept{
@Pointcut("execution(public void com.spring.service.Person.haveSleep())")
public void myPointcut(){}
@Around("myPointcut()")
public void stealPassword(ProceedingJoinPoint pjp) throws Throwable {
System.out.println(this.getClass().getName());
System.out.println("快要睡觉了");
pjp.proceed();
System.out.println(this.getClass().getName());
System.out.println("醒了,撤退");
}
}
与before和after不同的是,首先我要声明一个pointcut叫做myPointcut方法,myPointcut()方法里面是不需要写代码的,写了也不会执行,Spring只是用到了myPointcut()方法的方法名而已。之后的@Around是利用了myPointcut()的名字,表示切入点@Pointcut("execution(public void com.spring.service.Person.haveSleep())")这里。
pjp.proceed()是用于表示业务代码,在这里就是haveSleep()方法。
2、修改Person方法
package com.spring.service;
import org.springframework.stereotype.Component;
@Component
public class Person {
public void haveSleep()
{
System.out.println(this.getClass().getName());
System.out.println("睡觉了");
}
}
3、测试代码
package com.spring.service.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.service.Person;
public class PersonTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ctx = new ClassPathXmlApplicationContext("springbeans.xml");
Person person = (Person) ctx.getBean("person");
person.haveSleep();
}
}
测试结果
com.spring.aop.LeoIncept
快要睡觉了
com.spring.service.Person
睡觉了
com.spring.aop.LeoIncept
醒了,撤退