AOP:面向切面编程,相当于OOP面向对象编程。
Spring的AOP的存在目的是为了解耦,AOP可以让一组类共享相同的行为。
Spring支持AspectJ的注解切面编程:
(1)使用@Aspect声明是一个切面
(2)使用@Afte、@Before、@Around定义通知/建言,可以直接将拦截规则(切点)作为参数。
(3)为了使切点服用,可以使用@PointCut专门定义拦截规则,然后在@After、@Before、 @Advance的参数中调用。
(4)其中符合条件的每一个被拦截处为 连接点(JoinPoint)
eg:
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import java.lang.annotation.Documented; 4 import java.lang.annotation.ElementType; 5 import java.lang.annotation.Retention; 6 import java.lang.annotation.RetentionPolicy; 7 import java.lang.annotation.Target; 8 9 /** 10 * 11 * Makedate:2018年3月21日 下午1:01:48 12 * @author dong 13 * @version %I%, %G% 14 * @since 1.0 15 * 注解类(jdk1.5之后没设定特殊关键字而已) 16 * 功能:拦截规则的注解 17 * retention:保留 policy:政策 方针 18 * 19 * 20 **/ 21 @Target(ElementType.METHOD) 22 @Retention(RetentionPolicy.RUNTIME) 23 @Documented 24 public @interface Action { 25 String name(); 26 }
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import org.springframework.stereotype.Service; 4 5 @Service 6 public class DemoAnnotationService { 7 @Action(name="注解式拦截的add操作") 8 public String add() { 9 return "haha1"; 10 } 11 }
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import org.springframework.stereotype.Service; 4 5 /** 6 * 7 * 编写使用方法规则被拦截类 8 * 9 * Makedate:2018年3月21日 下午3:08:39 10 * @author dong 11 * @version %I%, %G% 12 * @since 1.0 13 * 14 * 15 */ 16 @Service 17 public class DemomethodService { 18 public String add() { 19 return "hehe2"; 20 } 21 }
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import java.lang.reflect.Method; 4 5 import org.aspectj.lang.JoinPoint; 6 import org.aspectj.lang.annotation.After; 7 import org.aspectj.lang.annotation.Aspect; 8 import org.aspectj.lang.annotation.Before; 9 import org.aspectj.lang.annotation.Pointcut; 10 import org.aspectj.lang.reflect.MethodSignature; 11 12 import org.springframework.stereotype.Component; 13 14 @Aspect //注解声明是一个切面 切面=通知+切点 15 @Component //让这个切面成为spring容器管理的Bean 16 public class LogAspect { 17 @Pointcut("@annotation(com.wisely.heighlight_spring4.ch1.aop.Action)") //注解声明切点 18 public void annotationPointCut() {}; 19 20 @After("annotationPointCut()") //注解声明通知 并使用@PointCut定义的切点 21 public void after(JoinPoint joinpoint) { 22 MethodSignature signature = (MethodSignature)joinpoint.getSignature(); 23 Method method = signature.getMethod(); 24 Action action = method.getAnnotation(Action.class); 25 System.out.println("注解式拦截:"+action.name()); //通过反射可以获得注解上的属性,做日志记录相关操作 26 } 27 28 @Before("execution(* com.wisely.heighlight_spring4.ch1.aop.DemomethodService.*(..))") 29 //@Before声明一个通知 这个通知直接使用拦截规则作为参数 30 public void before(JoinPoint joinpoint) { 31 MethodSignature signature = (MethodSignature)joinpoint.getSignature(); 32 Method method = signature.getMethod(); 33 System.out.println("方法规则式拦截,"+method.getName()); 34 } 35 }
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import org.springframework.context.annotation.ComponentScan; 4 import org.springframework.context.annotation.Configuration; 5 import org.springframework.context.annotation.EnableAspectJAutoProxy; 6 7 @Configuration 8 @ComponentScan("com.wisely.heighlight_spring4.ch1.aop") 9 @EnableAspectJAutoProxy //开启spring对aspecJ的支持 10 public class AopConfig { 11 12 }
1 package com.wisely.heighlight_spring4.ch1.aop; 2 3 import org.springframework.context.annotation.AnnotationConfigApplicationContext; 4 5 public class Main { 6 public static void main(String[] args) { 7 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); 8 DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class); 9 DemomethodService demomethodService = context.getBean(DemomethodService.class); 10 String add = demoAnnotationService.add(); 11 System.out.println("add---"+add); 12 13 String add2 = demomethodService.add(); 14 System.out.println("add2---"+add2); 15 context.close(); 16 } 17 }