首页 > 代码库 > Spring AOP实验之静态代理

Spring AOP实验之静态代理

1 AOP的概念和原理

1.1 AOP原理

  AOP(Aspect Oriented Programming),也就是面向方面编程的技术。AOP基于IoC基础,是对OOP的有益补充。

  AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。

  AOP正在成为软件开发的下一个光环。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。

  

1.2 AOP概念

  (1) 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。

  (2) 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

  (3) 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。

  (4) 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。

  (5) 引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。

  (6) 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。

  (7) AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

  (8) 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

2 AOP之静态代理

  2.1 业务介绍

  假设学生为核心类,学生做的事情是代理类。学生需要做的核心业务有:学习(study)、做家庭作业(homeWork);需要做的非核心业务为:准备上课(打开书本、预习)、准备做家庭作业(打开作业本、检查)。

  2.2 创建学生类接口:Student

1 package com.cqvie.proxy.static_;2 3 public interface Student {4 5     public void study(String study);6     public void homeWork(String homework);7 }

  2.3 创建学生实现类:StudentDao,并且实现学生接口(Student)

 1 package com.cqvie.proxy.static_; 2  3 public class StudentDao implements Student { 4  5     @Override 6     public void study(String study) { 7         System.err.println("今天的学习内容是:" + study); 8     } 9 10     @Override11     public void homeWork(String homework) {12         System.err.println("今天的家庭作业是:" + homework);13     }14 15 }

  2.4 创建一个学生的代理类:Student_Proxy,并且实现学生接口

 1 package com.cqvie.proxy.static_; 2  3 /** 4  * 代理对象(Student_proxy)的目的是帮助核心对象(StudentDao)做非核心的事情。 5  * 但是代理对象(Student_proxy)必须和核心对象(StudentDao)实现共同的接口。 6  */ 7 public class Student_Proxy implements Student { 8  9     //定义一个学生接口 作为属性,目的是就是在处理完代理需要做的事情之后调用学生需要做的核心业务,10     //但不是代理具体去做这些核心的事情,只是调用它们而已。11     private Student stu;12     13     //创建一个代理的参数为学生接口 的构造函数14     public Student_Proxy(Student stu) {15         this.stu = stu;16     }17 18     @Override19     public void study(String study) {20         21         //这个是代理(Student_proxy)准备学习前需要做的流程:    22         System.out.println("代理:打开书本");23         System.out.println("代理:提前预习");24         System.out.println("*****************");25         26         //通过定义的属性,并且在调用Student_proxy的含参数的构造函数创建相对应的实例,调用这个具体的实例的方法27         stu.study(study); 28         29         //这个是代理(G3Student_proxy)准备 后需要做的流程:30         System.out.println("*****************");31         System.out.println("代理:课后复习");32         System.out.println("代理:关闭书本");33         System.out.println();34     }35 36     @Override37     public void homeWork(String homework) {38         39         //这个是代理(Student_proxy)准备做作业前需要做的流程:    40         System.out.println("代理:打开作业本");41         System.out.println("代理:准备笔");42         System.out.println("*****************");43         44         //通过定义的属性,并且在调用Student_proxy的含参数的构造函数创建相对应的实例,调用这个具体的实例的方法45         stu.homeWork(homework); 46         47         //这个是代理(G3Student_proxy)准备做作业后需要做的流程:48         System.out.println("*****************");49         System.out.println("代理:检查作业");50         System.out.println("代理:关闭作业本");51         System.out.println();52     }53 54 }

  2.5 进行测试,定义测试类Test

 1 package com.cqvie.proxy.static_; 2  3 public class Test { 4  5     public static void main(String[] args) { 6          7         //创建一个代理对象 8         Student stu = new Student_Proxy(new StudentDao()); 9         //通过这个代理对象执行相关的方法(代理对象和核心对象有共同接口)10         stu.study("数学");11         stu.homeWork("8 * 9 = ?");12     }13 14 }

6. 运行效果如图所示

 技术分享技术分享

 

Spring AOP实验之静态代理