ImageVerifierCode 换一换
格式:DOCX , 页数:21 ,大小:327.07KB ,
资源ID:25072362      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/25072362.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ioc和aop相关资料.docx)为本站会员(b****9)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ioc和aop相关资料.docx

1、ioc和aop相关资料Spring IOC核心源码学习(一) 本文主要以spring ioc容器基本代码骨架为切入点,理解ioc容器的基本代码组件结构,各代码组件细节剖析将放在后面的学习文章里。 关于IOC容器IoC容器:最主要是完成了完成对象的创建和依赖的管理注入等等。先从我们自己设计这样一个视角来考虑:所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们可配置的文件。对象和对象关系怎么表示?可以用xml,properties文件等语义化配置

2、文件表示。描述对象关系的文件存放在哪里?可能是classpath,filesystem,或者是URL网络资源,servletContext等。回到正题,有了配置文件,还需要对配置文件解析。不同的配置文件对对象的描述不一样,如标准的,自定义声明式的,如何统一? 在内部需要有一个统一的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。如何对不同的配置文件进行解析?需要对不同的配置文件语法,采用不同的解析器。 基于以上问题,对应过来,刚好是 spring ioc 容器抽象的的几个主要接口:ResourceBeanDefinitionBeanDefinitionReaderBeanFactor

3、yApplicationContext以上五个都是接口,都有各式各样的实现,正是这5个接口定义了spring ioc容器的基本代码组件结构。而其组件各种实现的组合关系组成了一个运行时的具体容器。 各代码组件详解1.Resource是对资源的抽象,每一个接口实现类都代表了一种资源类型,如ClasspathResource、URLResource,FileSystemResource等。每一个资源类型都封装了对某一种特定资源的访问策略。它是spring资源访问策略的一个基础实现,应用在很多场景。 具体可以参考文章:Spring 资源访问剖析和策略模式应用 2.BeanDefinition用来抽象和

4、描述一个具体bean对象。是描述一个bean对象的基本数据结构。3.BeanDefinitionReaderBeanDefinitionReader将外部资源对象描述的bean定义统一转化为统一的内部数据结构BeanDefinition。对应不同的描述需要有不同的Reader。如XmlBeanDefinitionReader用来读取xml描述配置的bean对象。 4.BeanFactory用来定义一个很纯粹的bean容器。它是一个bean容器的必备结构。同时和外部应用环境等隔离。BeanDefinition是它的基本数据结构。它维护一个BeanDefinitions Map,并可根据BeanD

5、efinition的描述进行bean的创建和管理。 5.ApplicationContext从名字来看叫应用上下文,是和应用环境息息相关的。没错这个就是我们平时开发中经常直接使用打交道的一个类,应用上下文,或者也叫做spring容器。其实它的基本实现是会持有一个BeanFactory对象,并基于此提供一些包装和功能扩展。为什么要这么做呢?因为BeanFactory实现了一个容器基本结构和功能,但是与外部环境隔离。那么读取配置文件,并将配置文件解析成BeanDefinition,然后注册到BeanFactory的这一个过程的封装自然就需要ApplicationContext。Applicatio

6、nContext和应用环境细细相关,常见实现有ClasspathXmlApplicationContext,FileSystemXmlApplicationContext,WebApplicationContext等。Classpath、xml、FileSystem、Web等词都代表了应用和环境相关的一些意思,从字面上不难理解各自代表的含义。当然ApplicationContext和BeanFactory的区别远不止于此,有:1. 资源访问功能:在Resource和ResourceLoader的基础上可以灵活的访问不同的资源。2. 支持不同的信息源。3. 支持应用事件:继承了接口Applica

7、tionEventPublisher,这样在上下文中为bean之间提供了事件机制。 以上5个组件基本代表了ioc容器的一个最基本组成,而组件的组合是放在ApplicationContext的实现这一层来完成。 以ClasspathXmlApplicationContext 容器实现为例,其组合关系如下: ClassPathXmlApplicationContext的refresh() 方法负责完成了整个容器的初始化。为什么叫refresh?也就是说其实是刷新的意思,该IOC容器里面维护了一个单例的BeanFactory,如果bean的配置有修改,也可以直接调用refresh方法,它将销毁之前的

8、BeanFactory,重新创建一个BeanFactory。所以叫refresh也是能理解的。以下是Refresh的基本步骤:1.把配置xml文件转换成resource。resource的转换是先通过ResourcePatternResolver来解析可识别格式的配置文件的路径(如classpath*:等),如果没有指定格式,默认会按照类路径的资源来处理。 2.利用XmlBeanDefinitionReader完成对xml的解析,将xml Resource里定义的bean对象转换成统一的BeanDefinition。3.将BeanDefinition注册到BeanFactory,完成对Bean

9、Factory的初始化。BeanFactory里将会维护一个BeanDefinition的Map。当getBean的时候就会根据调用BeanFactory,根据bean的BeanDifinition来实例化一个bean。当然根据bean的lazy-init、protetype等属性设置不同以上过程略有差别。 refresh()代码如下:Java代码 1 public void refresh() throws BeansException, IllegalStateException 2 synchronized (this.startupShutdownMonitor) 3 / Prepar

10、e this context for refreshing. 4 prepareRefresh(); 5 6 / Tell the subclass to refresh the internal bean factory. 7 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 8 9 / Prepare the bean factory for use in this context. 10 prepareBeanFactory(beanFactory); 11 12 try 13 / Allows

11、 post-processing of the bean factory in context subclasses. 14 postProcessBeanFactory(beanFactory); 15 16 / Invoke factory processors registered as beans in the context. 17 invokeBeanFactoryPostProcessors(beanFactory); 18 19 / Register bean processors that intercept bean creation. 20 registerBeanPos

12、tProcessors(beanFactory); 21 22 / Initialize message source for this context. 23 initMessageSource(); 24 25 / Initialize event multicaster for this context. 26 initApplicationEventMulticaster(); 27 28 / Initialize other special beans in specific context subclasses. 29 onRefresh(); 30 31 / Check for

13、listener beans and register them. 32 registerListeners(); 33 34 / Instantiate all remaining (non-lazy-init) singletons. 35 finishBeanFactoryInitialization(beanFactory); 36 37 / Last step: publish corresponding event. 38 finishRefresh(); 39 40 41 catch (BeansException ex) 42 / Destroy already created

14、 singletons to avoid dangling resources. 43 beanFactory.destroySingletons(); 44 45 / Reset active flag. 46 cancelRefresh(ex); 47 48 / Propagate exception to caller. 49 throw ex; 50 51 52 以上的obtainFreshBeanFactory是很关键的一个方法,里面会调用loadBeanDefinition方法,如下:Java代码 53 protected void loadBeanDefinitions(Defa

15、ultListableBeanFactory beanFactory) throws IOException 54 / Create a new XmlBeanDefinitionReader for the given BeanFactory. 55 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); 56 57 / Configure the bean definition reader with this contexts 58 / resource loadin

16、g environment. 59 beanDefinitionReader.setResourceLoader(this); 60 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this); 61 62 / Allow a subclass to provide custom initialization of the reader, 63 / then proceed with actually loading the bean definitions. 64 initBeanDefinitionRead

17、er(beanDefinitionReader); 65 loadBeanDefinitions(beanDefinitionReader); 66 LoadBeanDifinition方法很关键,这里特定于整个IOC容器,实例化了一个XmlBeanDefinitionReader来解析Resource文件。关于Resource文件如何初始化和xml文件如何解析都在Java代码 67 loadBeanDefinitions(beanDefinitionReader); 里面的层层调用完成,这里不在累述。小结 Spring的扩展性是毋庸置疑的,学习spring的设计是一个很好的实践理论结合。主要

18、个人觉得有几点:1. 框架顶层的设计有着很好的抽象,遵循面向接口编程的规范。Resource、BeanFactory、ApplicationContext都是非常好的接口抽象,非常明确的定义了该组件的一些功能。2. 利用组合模式。3. 个组件的实现里大量使用了模板方法模式,提升了同一组件代码的复用性。4. 各种设计保留了扩展的接口,很多基于spring的框架都可以很容易的介入实现了自己的一些扩展。5. 框架里采用里很多经典的设计模式,如代理、装饰、策略等等。本文的目标: 从实现的角度来认识SpringAOP框架。 观察的角度: 从外部接口,内部实现,组成部分,执行过程四个方面来认识Spring

19、AOP框架。 本文的风格: 首先列出AOP的基本概念; 其次介绍框架所涉及到的核心组件列表,组件之间的结构关系图; 然后细化结构图中的部分; 接下来是一个简单的sample; 最后是后记部分。 注: 1.本文的源代码基于Spring2.x。Spring的源代码也处于演变中,但对基础代码的影响并不大。 2.本文是对Spring IoC容器实现的结构分析的姊妹帖。 正文: Spring AOP框架涉及的基本概念介绍: 关注点(concern):一个关注点可以是一个特定的问题、概念、或是应用程序的兴趣区间-总而言之,应用程序必须达到的一个目标。 核心关注点(core concern):业务功能模块,

20、如:存款模块,取款模块,转账模块等, 横切关注点(crosscutting concern):非功能性的、横切性模块,如:安全性管理,事务管理,性能监控等。 方面(aspect):一个方面是对一个横切关注点的模块化,它将那些原本散落在各处的、用于实现这个关注点的代码归整到一处。 连接点(join point):程序执行过程中的一点,如: 字段访问:读、写实例变量; 方法调用:对方法(包括构造方法)的调用; 异常抛出:特定的异常被抛出。 切入点(pointcut):一组连接点的总称,用于指定某个增强应该在何时被调用。切入点常用正则表达式或别的通配符语法来描述,有些AOP实现技术还支持切入点的组合

21、。 增强(advice):在特定连接点执行的动作。很多AOP框架都以拦截器(interceptor)的形式来表现增强-所谓拦截器是这样的一个 对象:当连接点被调用时,它会收到一个回调消息。基本的增强有: 前增强(BeforeAdvice):在连接点调用之前,首先调用增强; 后增强(AfterAdvice):在连接点调用之后,再调用增强,在AspectJ中,后增强又分为三种: AfterReturningAdvice:在调用成功完成(没有异常抛出)之后。 AfterThrowingAdvice:在抛出某种特定类型(或其子类型)的异常之后。 AfterAdvice:在连接点的任何调用之后,不管调用

22、是否抛出异常。 环绕增强(AroundAdvice):这类增强可以完全控制执行流程。除了完成本身的工作之外,它还需要负责主动调用连接点,促使真实的操作发生(proceed)- 这通常是通过调用某个特定的方法来完成的。 引介(introduction):为一个现有的Java类或接口添加方法或字段。这种技术可以用于实现Java中的多继承,或者给现有对象模型附加新的API。 混入继承(mixin inheritance):一个“混入类”封装了一组功能,这组功能可以被混入到现有的类当中,并且无须使用传统的继承手段。在AOP这里,混入是通过引介来实现的。在Java语言中,可以通过混入来模拟多继承。 织入

23、(weaving):将方面整合到完整的执行流程(或完整的类,此时被织入的便是引介中)。 拦截器(initerceptor):很多AOP框架用它来实现字段和方法的拦截(interception)。随之而来的就是在连接点(如方法拦截)处挂接一条拦截器链(interceptor chain),链条上的每个拦截器通常会调用下一个拦截器。 AOP代理(AOP proxy):即被增强(advise)的对象引用-也就是说,AOP增强将在其上执行的这样一个对象引用。 目标对象(target object):位于拦截器链末端的对象实例-这个概念只存在于那些使用了拦截机制的框架之中。 注:上述概念描述引自Expe

24、rt One-on-One J2EE Development without EJB中第八章对AOP概念描述部分,更多精彩部分可以参阅本章的完整内容。 上述概念已被Spring AOP框架很好的实现,相关组件: Advisor 组件, Advice 组件, Pointcut 组件, Advised 组件, AopProxy 组件, AopProxyFactory 组件, 图1. 图1是对增强、切入点、方面、AOP代理之间依赖关系的全景图。 增强和切入点组成一个方面,方面信息与目标对象信息被组织到Advised中,AopProxyFactory通过Advised中保存的信息生成AopProxy

25、对象,调用AopProxy.getProxy()方法即可获得增强后的对象。 这里要着重了解的是不同的增强子类型,不同的切入点子类型, 对于不同的切入点子类型最重要的两种子类型:静态切入点,动态切入点, 静态切入点:根据部署阶段的信息选择增强,如“拦截特定类的所有getter方法”; 动态切入点:根据运行时的信息选择增强,如“如果某方法的返回值为null,则将其纳入某切入点”。 图2. 图2是对图1中Advisor与Pointcut的实现细化,图中类之间的关系直观上有点乱,但细看下关系还是相当清晰的, 以Advisor结尾的是方面类型,以Pointcut结尾的是切入点类型, Advisor与Po

26、intcut的复用关系分两类:一类是组合复用,另一类是具体继承复用, 组合复用例子 如:RegexpMethodPointcutAdvisor 与 AbstractRegexpMethodPointcut之间的关系, NameMatchMethodPointcutAdvisor 与 NameMatchMethodPointcut之间的关系, 具体继承复用例子 如:StaticMethodMatcherPointcutAdvisor 与 StaticMethodMatcherPointcut 之间的关系, DynamicMethodMatcherPointcutAdvisor 与 Dynamic

27、MethodMatcherPointcut 之间的关系, 图3. 图3是对图1中生成AopProxy对象的实现细化, AopProxyFactory通过AdvisedSupport提供的信息生成AopProxy对象,AopProxy对象的生成分两类方式:一类是动态代理,另一类是字节码增强; 需要注意的是,ProxyFactory与ProxyFactoryBean并不是功能实现的必要部分,主要目的为编程式使用代理提供便利的API。 下面是一个简单的sample: Java代码 1 /目标对象接口. 2 public interface Target 3 public String play(in

28、t arg); 4 5 /目标对象实现. 6 public class TargetImpl implements Target 7 8 public String play(int arg) 9 System.out.println(play method.); 10 return Target: + arg; 11 12 13 /前置增强 14 public class MyBeforeAdvice implements MethodBeforeAdvice 15 public void before(Method method, Object args, Object target) 1

29、6 throws Throwable 17 System.out.println(method.getName(); 18 System.out.println(before method!); 19 20 21 /后置增强 22 public class MyAfterAdvice implements AfterReturningAdvice 23 public void afterReturning(Object returnValue, Method method, 24 Object args, Object target) throws Throwable 25 System.ou

30、t.println(returnValue + :after method); 26 27 28 /切入点实现 29 public class MyPointcut implements Pointcut 30 31 public ClassFilter getClassFilter() 32 33 return new ClassFilter() 34 35 public boolean matches(Class arg0) 36 if (arg0 = TargetImpl.class) 37 return true; 38 39 return false; 40 41 42 ; 43 44 45 public MethodMatcher getMethodMatcher() 46 47 return new MethodMatcher() 48 49 public boolean isRuntime() 50 51 return

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1