`
H_eaven
  • 浏览: 31379 次
  • 性别: Icon_minigender_1
  • 来自: 鲨堡
文章分类
社区版块
存档分类
最新评论

对Spring AOP框架实现的结构分析

阅读更多
本文的目标:
从实现的角度来认识SpringAOP框架。

观察的角度:
从外部接口,内部实现,组成部分,执行过程四个方面来认识SpringAOP框架。

本文的风格:
首先列出AOP的基本概念;
其次介绍框架所涉及到的核心组件列表,组件之间的结构关系图;
然后细化结构图中的部分;
接下来是一个简单的sample;
最后是后记部分。

注:
1.本文的源代码基于Spring2.x。Spring的源代码也处于演变中,但对基础代码的影响并不大。
2.本文是对Spring IoC容器实现的结构分析的姊妹帖。

正文:
Spring AOP框架涉及的基本概念介绍:
关注点(concern):一个关注点可以是一个特定的问题、概念、或是应用程序的兴趣区间--总而言之,应用程序必须达到的一个目标。
核心关注点(core concern):业务功能模块,如:存款模块,取款模块,转账模块等,
横切关注点(crosscutting concern):非功能性的、横切性模块,如:安全性管理,事务管理,性能监控等。

方面(aspect):一个方面是对一个横切关注点的模块化,它将那些原本散落在各处的、用于实现这个关注点的代码归整到一处。

连接点(join point):程序执行过程中的一点,如:
字段访问:读、写实例变量;
方法调用:对方法(包括构造方法)的调用;
异常抛出:特定的异常被抛出。

切入点(pointcut):一组连接点的总称,用于指定某个增强应该在何时被调用。切入点常用正则表达式或别的通配符语法来描述,有些AOP实现技术还支持切入点的组合。

增强(advice):在特定连接点执行的动作。很多AOP框架都以拦截器(interceptor)的形式来表现增强--所谓拦截器是这样的一个
           对象:当连接点被调用时,它会收到一个回调消息。基本的增强有:
   前增强(BeforeAdvice):在连接点调用之前,首先调用增强;
   后增强(AfterAdvice):在连接点调用之后,再调用增强,在AspectJ中,后增强又分为三种:
AfterReturningAdvice:在调用成功完成(没有异常抛出)之后。
AfterThrowingAdvice:在抛出某种特定类型(或其子类型)的异常之后。
AfterAdvice:在连接点的任何调用之后,不管调用是否抛出异常。
  环绕增强(AroundAdvice):这类增强可以完全控制执行流程。除了完成本身的工作之外,它还需要负责主动调用连接点,促使真实的操作发生(proceed)-- 这通常是通过调用某个特定的方法来完成的。

引介(introduction):为一个现有的Java类或接口添加方法或字段。这种技术可以用于实现Java中的多继承,或者给现有对象模型附加新的API。

混入继承(mixin inheritance):一个“混入类”封装了一组功能,这组功能可以被"混入"到现有的类当中,并且无须使用传统的继承手段。在AOP这里,混入是通过引介来实现的。在Java语言中,可以通过混入来模拟多继承。

织入(weaving):将方面整合到完整的执行流程(或完整的类,此时被织入的便是引介中)。

拦截器(initerceptor):很多AOP框架用它来实现字段和方法的拦截(interception)。随之而来的就是在连接点(如方法拦截)处挂接一条拦截器链(interceptor chain),链条上的每个拦截器通常会调用下一个拦截器。

AOP代理(AOP proxy):即被增强(advise)的对象引用--也就是说,AOP增强将在其上执行的这样一个对象引用。
目标对象(target object):位于拦截器链末端的对象实例--这个概念只存在于那些使用了拦截机制的框架之中。

注:上述概念描述引自《Expert One-on-One J2EE Development without EJB》中第八章对AOP概念描述部分,更多精彩部分可以参阅本章的完整内容。
上述概念已被Spring AOP框架很好的实现,相关组件:
Advisor 组件,
Advice   组件,
Pointcut 组件,
Advised 组件,
AopProxy 组件,
AopProxyFactory 组件,

图1.

图1是对增强、切入点、方面、AOP代理之间依赖关系的全景图。
增强和切入点组成一个方面,方面信息与目标对象信息被组织到Advised中,AopProxyFactory通过Advised中保存的信息生成AopProxy
对象,调用AopProxy.getProxy()方法即可获得增强后的对象。
这里要着重了解的是不同的增强子类型,不同的切入点子类型,
对于不同的切入点子类型最重要的两种子类型:静态切入点,动态切入点,
静态切入点:根据部署阶段的信息选择增强,如“拦截特定类的所有getter方法”;
动态切入点:根据运行时的信息选择增强,如“如果某方法的返回值为null,则将其纳入某切入点”。

图2.

图2是对图1中Advisor与Pointcut的实现细化,图中类之间的关系直观上有点乱,但细看下关系还是相当清晰的,
以Advisor结尾的是方面类型,以Pointcut结尾的是切入点类型,
Advisor与Pointcut的复用关系分两类:一类是组合复用,另一类是具体继承复用,
组合复用例子 如:RegexpMethodPointcutAdvisor 与 AbstractRegexpMethodPointcut之间的关系,
               NameMatchMethodPointcutAdvisor 与 NameMatchMethodPointcut之间的关系,
具体继承复用例子 如:StaticMethodMatcherPointcutAdvisor 与 StaticMethodMatcherPointcut 之间的关系,
          DynamicMethodMatcherPointcutAdvisor 与 DynamicMethodMatcherPointcut 之间的关系,

图3.

图3是对图1中生成AopProxy对象的实现细化,
AopProxyFactory通过AdvisedSupport提供的信息生成AopProxy对象,AopProxy对象的生成分两类方式:一类是动态代理,另一类是字节码增强;
需要注意的是,ProxyFactory与ProxyFactoryBean并不是功能实现的必要部分,主要目的为编程式使用代理提供便利的API。


下面是一个简单的sample:
//目标对象接口.
public interface Target {
	public String play(int arg);
}
//目标对象实现.
public class TargetImpl implements Target {

	public String play(int arg) {
		 System.out.println("play method....");
		return "[Target:]" + arg;
	}
}
//前置增强
public class MyBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		 System.out.println(method.getName());
		 System.out.println("before method!");
	}
}
//后置增强
public class MyAfterAdvice implements AfterReturningAdvice {
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		 System.out.println(returnValue + ":after method"); 
	}
}
//切入点实现
public class MyPointcut implements Pointcut {

	public ClassFilter getClassFilter() {
		 
		return new ClassFilter() {

			public boolean matches(Class arg0) {
				if (arg0 == TargetImpl.class) {
					return true;
				}
				return false;
			}
			
		};
	}

	public MethodMatcher getMethodMatcher() {
		 
		return new MethodMatcher() {

			public boolean isRuntime() {
				 
				return false;
			}

			public boolean matches(Method arg0, Class arg1) {
				
				if ("play".equals(arg0.getName())) {
					return true;
				}
				return false;
			}

			public boolean matches(Method arg0, Class arg1, Object[] arg2) {
				System.out.println("aaaaaa");
				if ("play".equals(arg0.getName())) {
					return true;
				}
				return false;
			}
			
		};
	}

}
public class Main {
	public static void main(String[] args) {
		 Target target = new TargetImpl();   //目标对象
		 Advice beforeAdvice = new MyBeforeAdvice(); //增强
		 Pointcut pointcut = new MyPointcut(); //切入点
		 DefaultPointcutAdvisor dda = new DefaultPointcutAdvisor(); //切面
		 dda.setAdvice(beforeAdvice);
		 dda.setPointcut(pointcut);
		 
		 AdvisedSupport advisedSupport = new AdvisedSupport(); //提供基本的编程方式,
		 advisedSupport.addAdvisor(dda);
		 advisedSupport.addAdvice(new MyAfterAdvice());
		 advisedSupport.addInterface(Target.class);
		 advisedSupport.setTarget(target);
		 AopProxy aopProxy = new DefaultAopProxyFactory().createAopProxy(advisedSupport);
		 Target proxy = (Target)aopProxy.getProxy();
		 System.out.println(proxy.play(200));
		 
		 ProxyFactory proxyFactory = new ProxyFactory();  //提供便利的编程方式.
		 proxyFactory.addAdvisor(dda);
		 proxyFactory.addInterface(Target.class);
		 proxyFactory.setTarget(target);
		 Target proxy2 = (Target)proxyFactory.getProxy();
		 System.out.println(proxy2.play(201));
		 
		 ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean(); //提供便利的配置方式
		 proxyFactoryBean.addAdvisor(dda);
		 proxyFactoryBean.addInterface(Target.class);
		 proxyFactoryBean.setTarget(target);
		 Target proxy3 = (Target)proxyFactoryBean.getObject();
		 System.out.println(proxy3.play(232));
	}
}


注:此处为了简单忽略了一些概念描述:
1.对引介,混入继承没有涉及。
2.对通知链的管理,如:同一切入点多个通知对象之间的执行顺序问题;
3.上述的描述是Spring AOP框架本身,所提供的使用方式是编程式,这种使用方式太过于低级,以至于我们在九成的情况下不会使用到,主流的使用方式是配置化的声明式使用方式,将AOP与IoC结合起来使用才能发挥出最大威力,ProxyFactoryBean提供了有限的声明式使用方式,但严格来说它仍是编程式,因为ProxyFactoryBean是一个FactoryBean,一个FactoryBean的目标就是以编程式替换复杂的配置式,而且最重要的是它暴露的API太过低级,配置文件中bean元素的abstract属性对配置文件的长度提供有限的帮助,自动代DefaultAdvisorAutoProxyCreator很好的隐藏了低级的API,DefaultAdvisorAutoProxyCreator是一个BeanPostProcessor,用于完成AOP框架与IoC容器的集成工作,但是这种方式依然没有解决需要同XXXAdvisor这样的低级API打交道的问题;
    随着spring2.x引入的xml元素<aop:config>及@Aspect注解的AspectJ描述性风格的出现,使用Spring AOP框架的使用达到完全的声明式标准,这种风格也使得Spring 事务框架受益,从TransactionProxyFactoryBean类到xml元素<tx:advice>、<aop:config>及@Transactional注解,
    使得我们只需关注高层描述,而无需涉及低级API。
附上DefaultAdvisorAutoProxyCreator的类结构图:


总结:
要全面理解AOP相关概念,回答下述问题是必须的。
1。AOP概念产生的背景,AOP所要解决的问题,AOP所涉及的概念,
2。实现一个AOP框架所需要注意的问题是什么,
3。不同AOP框架实现之间的比较,
4。AOP的一些副作用讨论。


参考目录:
《Expert One-on-One J2EE Development without EJB》
《Professional Java Development with the Spring Framework》
《Mastering AspectJ》
  • 大小: 132 KB
  • 大小: 161.8 KB
  • 大小: 107.6 KB
  • 大小: 93.3 KB
分享到:
评论

相关推荐

    Spring AOP框架实现的结构分析

    spring aop框架源码级分析 结构图

    深入解析Spring AOP源码:从原理到实现,全方位掌握Java AOP编程精髓

    Spring AOP(面向切面编程)作为Spring框架的一个重要部分,为Java开发者提供了一个强大而灵活的工具来切入代码执行流程,实现关注点的分离。通过详细解析Spring AOP的源码,本文揭示了其背后的核心原理和实现机制。...

    java面试难点讲解:hashmap,spring aop,classload,dubbo,zookeeper,session等。

    面试必考之HashMap源码分析与实现 探索JVM底层奥秘ClassLoader源码分析与案例讲解 面试必备技能之Dubbo企业实战 分布式框架Zookeeper之服务注册与订阅 互联网系统垂直架构之...无处不在的Spring AOP事务及踩过的坑

    Spring+3.x企业应用开发实战光盘源码(全)

     第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。  第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、...

    Spring源码解析4章150页+Spring3.2.4中文注释源码

    一阶段 1、Spring概述 2、一切从bean开始 3、俯瞰Spring架构设计 4、Spring源码下载 二阶段 1、什么是IOC/DI ...SpringMVC框架设计原理及手写实现 四阶段 Spring事务源码解析 需要其他源码请私信我

    陈开雄 Spring+3.x企业应用开发实战光盘源码.zip

     第6章:我们从Spring AOP的底层实现技术入手,一步步深入到Spring AOP的内核中,分析它的底层结构和具体实现。  第7章:对如何使用基于AspectJ配置AOP的知识进行了深入的分析,这包括使用XML Schema配置文件、...

    Spring原理篇.xmind

    包括内容:Spring体系结构、Spring重要接口讲解(BeanFactory继承体系、BeanDefinition继承体系、ApplicationContext继承体系)、IOC/DI(容器初始化流源码分析)、AOP原理(解析流程,代理流程,执行流程)、事务...

    基于J2EE架构的生产管理系统设计

    系统基于B/S 多层Web 体系结构,在J2EE 平台上利用...用Spring 的IOC 和AOP 技术对持 久层和业务逻辑层对象进行管理,为web 应用提供事务管理等基础服务。在表示层 使用了J2EE 新兴框架JSF,实现高效灵活的web 端开发。

    Java Web程序设计教程

    2.4.2熟悉helloworld框架结构 29 本章小结 32 课后练习 32 第3章jsp和servlet 33 3.1开发第一个jsp+servlet应用 33 3.1.1创建工程 33 3.1.2编写程序 34 3.1.3部署应用 35 3.2认识jsp 36 3.2.1jsp的工作原理...

    基于SSM的客户关系管理系统.zip

    该系统采用先进的技术架构,包括了数据库、Web 应用程序和前端界面,以实现对客户数据的集中管理和分析。首先,Spring框架提供了一个强大的依赖注入(DI)功能,可以简化项目开发过程,降低代码耦合度。通过使用Spring...

    j2ee 架构设计 (SSH典型结构解析)

    分析多层结构优点 具体讲解每个层次的实现技巧 第二部分:介绍组织层次关联利器(Spring) 快速入门 Factory模式 IOC模式 AOP模式 演练Spring的威力 第三部分:介绍日志管理利器(Log4j) 快速入门 演练Log4j的优越...

    论文研究-典型数控延迟单元的归类分析.pdf

    结合AOP、反射、上下文传播、XML技术给出了一种新颖的访问控制实现方法,这种方法能够同基于MVC设计模式的框架有机地结合起来,不仅使访问控制代码集中管理,而且在实现访问控制的同时,保持了原有Web应用的松耦合...

    weixin135房屋租赁管理系统的设计与实现+ssm--论文pf.rar

    SSM集成了Spring的依赖注入和面向切面编程、Spring MVC的MVC框架以及MyBatis的持久层框架,使得开发更加高效、结构更加清晰。 技术介绍: Spring:一个开源的轻量级Java SE/Java EE全功能栈框架,提供了IoC容器和...

    #ssm080mysql高校心理测评设计与分析系统.zip

    Spring提供了控制反转(IoC)和面向切面(AOP)等特性,简化了开发过程;Spring MVC用于构建Web应用程序,处理HTTP请求和响应;而MyBatis则是一个优秀的持久层框架,简化了数据库操作。 这些项目的开发旨在为用户...

    Java高级工程师简历模板18k+

    基本资料 教育背景 求职意向 专业技能 项目经验 工作经历 自我评价 ◆专业技能 1.具有扎实的Java基础,对面向对象编程有深刻的理解,...6.熟练掌握SSM等框架使用,熟悉spring IOC ,springAop springs事物核心

    xmljava系统源码-Myioc:这是一个简单的IoC容器实现

    IoC,反射,设计模式等知识都能讲清楚,但是感觉由于平时使用框架做Web后台开发的原因,明明每天都在接触这些东西,但是又没有真正在使用它们,只是使用了Spring等框架基于它们来实现的服务,纸上得来终觉浅,不练习...

    计算机软件项目设计方案(2020).docx

    在基于以上数据管理效率低、操作不方便等原因的基础上,XX有限公司干部数据管理需要实现对企业仼职干部统一、规范的信息化管理,提高企业内部的管理效率,实现对职位分布总体情况进行了解、管理、考核,使干部仼用、选拔...

    低清版 大型门户网站是这样炼成的.pdf

    6.4.2 spring 2.5集成mvc框架struts 2 411 6.4.3 ssh 2组合框架的基本开发步骤—eportal启程 414 6.5 小结 423 第2篇 实践篇 第7章 ssh 2热身——构建新闻发布系统 427 7.1 门户网站新闻资讯基本分类 427 7.2 ...

    java-ee电子商城系统课程设计.doc

    简单来说,Spring 是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。 Hibernate 是一个开放源代码的对象关系映射框架,它对JDBC 进行了非常轻量级的对象封装,使得Java 程序员可以随心所欲的使用对象编程思维...

    基于JavaWEB+SSM+mysql框架构建的在线商城系统源码+数据库+项目说明(课程设计).zip

    * [小小商城项目概述 —— 需求分析、数据表设计、原型设计、多层结构设计、项目规划][4] * [SSM开发 | 合理配置 mybatis-generator,隔离机器生成代码和额外增加代码][5] * [SSM开发 | 开发自定义插件,使 ...

Global site tag (gtag.js) - Google Analytics