Spring AOP
1、目的:
Spring AOP的存在是为了解耦,AOP可以让一组类共享相同的行为。在OOP(面向对象编程)中,一般是通过继承类和实现接口等方式实现一组类共享某一相同的行为,java中类只能单继承,阻碍了更多行为添加到一组类上,AOP弥补了以上不足。
2、实现
Spring 有两种方式实现AOP:基于注解拦截和给予方法规则拦截,本文将在同一工程中实现两者。
首先用eclipse创建一个maven工程,在pom文件中加入如下依赖关系:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zy</groupId> <artifactId>testAop</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>testAop</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.6.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>5.0.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> </dependencies> </project>
然后,编写拦截规则的注解:
package com.zy.testAop; 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; /** * 方法注解 * @author user * */ @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Action { String name(); }
然后编写使用注解的被拦截类:
package com.zy.testAop; import org.springframework.stereotype.Service; @Service public class DemoAnnotationService { @Action(name = "注解式拦截的add操作") public void add() { System.out.println("真正执行到了DemoAnnotationService的add方法"); System.out.println("DemoAnnotationService.add方法结束"); } }
然后编写使用方法规则的被拦截类
package com.zy.testAop; import org.springframework.stereotype.Service; @Service public class DemoMethodService { public void add() { System.out.println("DemoMethodService.add()"); } }
然后编写切面:
package com.zy.testAop; 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 public class LogAspect { @Pointcut("@annotation(com.zy.testAop.Action)") public void annotationPointCut() { System.out.println("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.zy.testAop.DemoMethodService.*(..))") public void before(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature)joinPoint.getSignature(); Method method = signature.getMethod(); System.out.println("方法规则式拦截," + method.getName()); } }
然后编写一个配置类(用于开启spring对aspectJ的):
package com.zy.testAop; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Configuration @ComponentScan("com.zy.testAop") @EnableAspectJAutoProxy public class AopConfig { }
最后编写运行类,即可大功告成啦:
package com.zy.testAop; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { 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(); } }
这只是一个spring aop的小例子,带你熟悉aop,对于aop原理你可以直接阅读其源码
这个工程的github地址:点击打开链接.有兴趣的同学可以拉一下代码看看