一、AOP术语
1、通知(advice):定义了切面何时(@Before, @After, @AfterThrowing ,@AfterReturning,@Around )使用
2、连接点(join point):在应用执行过程中能够被插入切面的一个点。
3、切点(pointcut):对连接点中的哪些连接点进行织入切面(切点是指匹配到的某些连接点)
4、切面(aspect):是通知加切点的给合
5、引入(introduction):允许我们向现有的类添加新的方法和属性(对已有的类引入新的接口,接口里定义了新的方法和属性)
6、织入(weaving):把切面应用到目标对象并创建新的代理对象的过程(编译期:Aspectj的织入编译器就是以这种方式;类加载期:AspectJ 5的加载时织入就是以这种方式织入;运行期:spring AOP就是以这种方式织入切面的)
二、AOP术语在应用程序中的对应
//正常的业务服务层 @Service public class HelloWorldFirstImpl implements HelloWorld { @Override public void printHelloWorld() { System.out.println("This is HelloWorldFirstImpl.printHelloWorld()"); } @Override public void doPrint() { try { Thread.sleep(1000); } catch (Exception ex) { System.out.println(ex.getMessage()); } System.out.println("This is HelloWorldFirstImpl.doPrint()"); } }
//切面(需要切入的服务 : 获取执行时间) @Aspect @Component public class TimeHandlerAspect { /** * advice 定义前置通知 // 连接点:* cc.freshair.springaop.services.impl.*.*(..) */ @Before("execution(* cc.freshair.springaop.services.impl.*.doPrint(..))") public void printTime() { System.out.println("CurrentTime:" + System.currentTimeMillis()); } @Around("execution(* cc.freshair.springaop.services.impl.*.doPrint(..))") public Object processTime(ProceedingJoinPoint point) throws Throwable { long beginTime = System.currentTimeMillis(); Object result = point.proceed(); long endTime = System.currentTimeMillis(); System.out.println("process time:" + (endTime - beginTime)); return result; } }
//被引入的新类(主要是新类的方法或者属性,此处是将likeSmoke()方法引入到HelloWorldFirstImpl类中) @Service public class Man implements Person { @Override public void likeSmoke() { System.out.println("喜欢抽烟"); } } //定义要引入的新类与目标类之间的关联 @Aspect @Component public class IntroductionAspect { @DeclareParents(value = "cc.freshair.springaop.services.impl.*", defaultImpl = Man.class) public static Person person; }
//应用程序启动的入口 @SpringBootApplication @EnableAspectJAutoProxy public class SpringAopApplication { public static void main(String[] args) { SpringApplication.run(SpringAopApplication.class, args); } }
//web应用的请求控制器 @RestController @RequestMapping("/index") public class IndexController { @Autowired public HelloWorld helloWorld; @Resource public Person person; @RequestMapping("/index") public String index() { helloWorld.doPrint(); //调用AOP引入的方法 person = (Person)helloWorld; person.likeSmoke(); return "Hello World"; } }
1、通知(advice):TimeHandlerAspect 类的(@Before @Around) 描述在切入点(“什么时候”执行:before:之前 around:环绕,从开始到结束 )
2、连接点(joinpoint):HelloWorldFirstImpl类的 doPrint(), printHelloWorld()
3、切点(cutpoint):符合我们定义的规则的那些连接点 比如:doPrint()
4、切面(aspect):由切点和通知相结合而成的,定义通知应用到那些切入点上
5、引入点(intruduction):Man类+IntroductionAspect 类(将Man类的doSmoke方法引入到HelloWorldFirstImpl类上来)
6、织入(weaving):把切面的代码织入(应用)到目标函数的过程