spring笔记-AspectJ(AOP)
2018-05-20 本文已影响22人
兴浩
AspectJ主要使用注解的方式来实现AOP,Spring AOP偏重编程的方式
1.示例接口
public interface Waiter {
void greetTo(String name);
void serveTo(String name);
}
public class NaiveWaiter implements Waiter {
public void greetTo(String name) {
System.out.println("greet to "+name+"...");
}
public void serveTo(String name){
System.out.println("serving "+name+"...");
}
}
2.定义切面
2.1 使用Aspect注解定义一个切面
2.2 Before表示增强类型中的前置增强
2.3 execution表示切点表达式
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class PreGreetingAspect{
@Before("execution(* greetTo(..))")
public void beforeGreeting(){
System.out.println("How are you");
}
}
3.生成切面代理
3.1 使用AspectJProxyFactory
即编程模式
@Test
public void proxy(){
Waiter target = new NaiveWaiter();
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(target);
factory.addAspect(PreGreetingAspect.class);
Waiter proxy = factory.getProxy();
proxy.greetTo("John");
proxy.serveTo("John");
}
输出结果:
How are you
greet to John...
serving John...
3.2 xml模式
aop:aspectj-autoproxy是AnnotationAwareAspectJAutoProxyCreator的简约模式
<aop:aspectj-autoproxy/>
<!--bean class="org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"/-->
<bean id="waiter" class="aop.smart.advice.NaiveWaiter" />
<bean class="aop.smart.aspectj.example.PreGreetingAspect" />
3.2 注解模式(EnableAspectJAutoProxy)
@Configuration
@EnableAspectJAutoProxy
public class AspectJConfig {
@Bean("waiter")
public Waiter getWaiter()
{
return new NaiveWaiter();
}
@Bean
public PreGreetingAspect getPreGreetingAspect()
{
return new PreGreetingAspect();
}
}
4.增强类型
修改
public void serveTo(String name){
System.out.println("serving "+name+"...");
throw new RuntimeException();
}
@Aspect
public class TestGreetingAspect {
@Before("execution(* greetTo(..))")
public void beforeGreeting(){
System.out.println("beforeGreeting");
}
@AfterReturning("execution(* greetTo(..))")
public void afterReturningGreeting(){
System.out.println("afterReturningGreeting");
}
@Around("execution(* greetTo(..))")
public void aroudGreeting(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("before aroudGreeting before");
pjp.proceed();
System.out.println("after aroudGreeting");
}
@AfterThrowing("execution(* serveTo(..))")
public void afterThrowingGreeting() throws Throwable {
System.out.println("afterThrowingGreeting");
}
@After("execution(* serveTo(..))")
public void afterGreeting() throws Throwable {
System.out.println("afterGreeting");
}
}
结果输出
before aroudGreeting before
beforeGreeting
greet to John...
afterReturningGreeting
after aroudGreeting
serving John...
afterThrowingGreeting
afterGreeting
5.切点表达式
5.1@annotation
表示标记某个注解的所有方法
@AfterReturning("@annotation(aop.smart.anno.NeedTest)")
public void atAnnotaionTest(){
System.out.println("atAnnotaionTest() executed!");
}
@NeedTest
public void serveTo(String name){
System.out.println("serving "+name+"...");
//throw new RuntimeException();
}
5.2 execution
5.3 args和@args
5.4 within
6.命名切点
public class TestNamePointcut {
@Pointcut("within(com.smart.*)")
private void inPackage(){}
//
// @Pointcut("execution(* greetTo(..)))")
// protected void greetTo(){}
//
@Pointcut("inPackage() and greetTo()")
public void inPkgGreetTo(){}
}
@Before("TestNamePointcut.inPkgGreetTo()")
public void pkgGreetTo(){
System.out.println("--pkgGreetTo() executed!--");
}
7.排序(Ordered)
@Aspect
public class OrderGreetingAspect implements Ordered {
@Around("execution(* greetTo(..))")
public void beforeGreeting(ProceedingJoinPoint point) throws Throwable {
System.out.println("OrderGreetingAspect");
point.proceed();
}
@Override
public int getOrder() {
return 1;
}
}
@Aspect
public class Order2GreetingAspect implements Ordered {
@Around("execution(* greetTo(..))")
public void beforeGreeting(ProceedingJoinPoint point) throws Throwable {
System.out.println("Order2GreetingAspect");
point.proceed();
}
@Override
public int getOrder() {
return 2;
}
}
@Test
public void orderTest(){
Waiter target = new NaiveWaiter();
AspectJProxyFactory factory = new AspectJProxyFactory();
factory.setTarget(target);
factory.addAspect(OrderGreetingAspect.class);
factory.addAspect(Order2GreetingAspect.class);
Waiter proxy = factory.getProxy();
proxy.greetTo("John");
proxy.serveTo("John");
}
测试结果:
OrderGreetingAspect
Order2GreetingAspect
greet to John...
serving John...
8.绑定连接点信息
如上ProceedingJoinPoint
9.绑定连接点方法入参
@Around("execution(* greetTo(..)) && args(name)")
public void beforeGreeting(ProceedingJoinPoint point,String name) throws Throwable {
System.out.println("Order2GreetingAspect");
point.proceed();
}