spring AOP
什么是AOP?
1.点睛
AOP:面向切面编程,相对于OOP面向对象编程。
Spring的AOP的存在目的是为了解耦。AOP可以让一组类共享相同的行为。在OOP中只能通过继承类和实现接口,来使代码的耦合度增强,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP弥补了OOP的不足。
Spring支持AspectJ的注解式切面编程。
(1) 使用@Aspect声明一个切面
(2) 使用@After、@Before、@Around定义建言,可直接拦截规则作为参数。
(3) 其中@After、@Before、@Around参数的拦截规则为切点,为了使切点复用,可以使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。
(4) 其中符合条件的每一个被拦截处为连接点。
2.示例
(1) 添加sping aop支持AsPectJ依赖。
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.3.RELEASE</version> </dependency> <!--aop支持--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.1.6.RELEASE</version> </dependency> <!--aspectj支持--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.5</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.5</version> </dependency> </dependencies>
(2) 编写拦截规则的注解
目录结构
package com.demo.config; 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) public @interface Action { String name(); }
(3) 编写使用注解的被拦截类
package com.demo.service; import com.demo.config.Action; import org.springframework.stereotype.Service; @Service public class DemoAnnotationService { @Action(name = "注解式拦截的add操作") public void add(){ } }
(4) 编写使用方法规则被拦截类
package com.demo.service; import org.springframework.stereotype.Service; @Service public class DemoMethodService { public void add(){ } }
(5) 编写切面
package com.demo.aspect; import com.demo.config.Action; 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; import java.lang.reflect.Method; @Aspect @Component public class LogAspect { @Pointcut("@annotation(com.demo.config.Action)") public void annotationPointCut() { } @After("annotationPointCut()") 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.demo.service.DemoMethodService.*(..))") public void before(JoinPoint joinPoint){ System.out.println("LogAspect.before"); } }
(6) 配置类
package com.demo.config; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @ComponentScan("com.demo") @EnableAspectJAutoProxy public class AopConfig { }
(7) 运行
package com.demo; import com.demo.config.AopConfig; import com.demo.service.DemoAnnotationService; import com.demo.service.DemoMethodService; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); DemoAnnotationService demoAnnotationService = context.getBean(DemoAnnotationService.class); demoAnnotationService.add(); DemoMethodService demoMethodService = context.getBean(DemoMethodService.class); demoMethodService.add(); context.close(); } }