Spring 支持 AspectJ的注解式切面编程。AOP可以让一组类共享相同的行为。
注解
- 使用
@Aspect
声明一个切面。 - 使用
@After,@Before,@Around
定义建言(Advice
),可以直接拦截规则(切点)作为参数。 - 其中@After,@Before,@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用
@PointCut
专门定义拦截规则,然后在@After,@Before,@Around的参数中调用。 - 其中符合条件的每一个被拦截处为连接点(
JoinPoint
)。
示例
编写拦截规则的注解
package com.aop; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Action { String name(); }
编写使用注解的被拦截的类
package com.aop; import org.springframework.stereotype.Service; @Service public class DemoAnnotationService { @Action(name="注解释拦截的add操作") public void add() { System.out.println("DemoAnnotationService ---"); } }
编写使用方法规则的被拦截的类
package com.aop; import org.springframework.stereotype.Service; @Service public class DemoMethodService { public void add() { System.out.println("DemoMethodService ---"); } }
编写切点
package com.aop; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; @Aspect //声明一个切面 @Component //成为spring容器中的一个Bean public class LogAspect { @Pointcut("@annotation(com.aop.Action)")//声明切点 public void annotationPointCut() {}; @After("annotationPointCut()") //声明建言,并使用@Pointcut定义切点 public void after(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Action action = method.getAnnotation(Action.class); System.out.println("注解式拦截,在方法执行之后拦截: " + action.name());//通过反射获取注解上的属性 } @Before("execution(* com.aop.DemoMethodService.*(..))") public void before(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); System.out.println("方法规则式拦截,方法执行之前拦截:" + method.getName()); } }
编写配置类
package com.aop; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @ComponentScan("com.aop") @EnableAspectJAutoProxy//开启spring对AspectJ的支持 public class AopConfig { }
运行测试
package com.aop; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class AopMain { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class); DemoMethodService demoMethodService = context.getBean(DemoMethodService.class); demoAnnotationService.add(); demoMethodService.add(); context.close(); } }
运行结果
DemoAnnotationService --- 注解式拦截,在方法执行之后拦截: 注解释拦截的add操作 方法规则式拦截,方法执行之前拦截:add DemoMethodService ---
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载