- 浏览: 754085 次
- 性别:
- 来自: 郑州
文章分类
- 全部博客 (396)
- JAVA (50)
- ORACLE (22)
- HIBERNATE (1)
- SPRING (26)
- STRUTS (4)
- OTHERS (0)
- MYSQL (11)
- Struts2 (16)
- JS (33)
- Tomcat (6)
- DWR (1)
- JQuery (26)
- JBoss (0)
- SQL SERVER (0)
- XML (10)
- 生活 (3)
- JSP (11)
- CSS (5)
- word (1)
- MyEclipse (7)
- JSTL (1)
- JEECMS (2)
- Freemarker (8)
- 页面特效 (1)
- EXT (2)
- Web前端 js库 (2)
- JSON http://www.json.org (3)
- 代码收集 (1)
- 电脑常识 (6)
- MD5加密 (0)
- Axis (0)
- Grails (1)
- 浏览器 (1)
- js调试工具 (1)
- WEB前端 (5)
- JDBC (2)
- PowerDesigner (1)
- OperaMasks (1)
- CMS (1)
- Java开源大全 (2)
- 分页 (28)
- Eclipse插件 (1)
- Proxool (1)
- Jad (1)
- Java反编译 (2)
- 报表 (6)
- JSON (14)
- FCKeditor (9)
- SVN (1)
- ACCESS (1)
- 正则表达式 (3)
- 数据库 (1)
- Flex (3)
- pinyin4j (2)
- IBATIS (3)
- probe (1)
- JSP & Servlet (1)
- 飞信 (0)
- AjaxSwing (0)
- AjaxSwing (0)
- Grid相关 (1)
- HTML (5)
- Guice (4)
- Warp framework (1)
- warp-persist (1)
- 服务器推送 (3)
- eclipse (1)
- JForum (5)
- 工具 (1)
- Python (1)
- Ruby (1)
- SVG (3)
- Joda-Time日期时间工具 (1)
- JDK (3)
- Pushlet (2)
- JSP & Servlet & FTP (1)
- FTP (6)
- 时间与效率 (4)
- 二维码 (1)
- 条码/二维码 (1)
最新评论
-
ctrlc:
你这是从web服务器上传到FTP服务器上的吧,能从用户电脑上上 ...
jsp 往 FTP 上传文件问题 -
annybz:
说的好抽象 为什么代码都有两遍。这个感觉没有第一篇 和第二篇 ...
Spring源代码解析(三):Spring JDBC -
annybz:
...
Spring源代码解析(一):IOC容器 -
jie_20:
你确定你有这样配置做过测试? 请不要转载一些自己没有测试的文档 ...
Spring2.0集成iReport报表技术概述 -
asd51731:
大哥,limit传-1时出错啊,怎么修改啊?
mysql limit 使用方法
下面我们来看看Spring的AOP的一些相关代码是怎么得到Proxy的,让我们我们先看看AOP和Spring AOP的一些基本概念:
Advice:
通知,制定在连接点做什么,在Sping中,他主要描述Spring围绕方法调用注入的额外的行为,Spring提供的通知类型有:
before
advice,AfterReturningAdvice,ThrowAdvice,MethodBeforeAdvice,这些都是Spring
AOP定义的接口类,具体的动作实现需要用户程序来完成。
Pointcut:
切点,其决定一个advice应该应用于哪个连接点,也就是需要插入额外处理的地方的集合,例如,被某个advice作为目标的一组方法。Spring
pointcut通常意味着标示方法,可以选择一组方法调用作为pointcut,Spring提供了具体的切点来给用户使用,比如正则表达式切点
JdkRegexpMethodPointcut通过正则表达式对方法名进行匹配,其通过使用
AbstractJdkRegexpMethodPointcut中的对MethodMatcher接口的实现来完成pointcut功能:
- public final boolean matches(Method method, Class targetClass) {
- //这里通过放射得到方法的全名
- String patt = method.getDeclaringClass().getName() + "." + method.getName();
- for ( int i = 0 ; i < this .patterns.length; i++) {
- // 这里是判断是否和方法名是否匹配的代码
- boolean matched = matches(patt, i);
- if (matched) {
- for ( int j = 0 ; j < this .excludedPatterns.length; j++) {
- boolean excluded = matchesExclusion(patt, j);
- if (excluded) {
- return false ;
- }
- }
- return true ;
- }
- }
- return false ;
- }
public final boolean matches(Method method, Class targetClass) { //这里通过放射得到方法的全名 String patt = method.getDeclaringClass().getName() + "." + method.getName(); for (int i = 0; i < this.patterns.length; i++) { // 这里是判断是否和方法名是否匹配的代码 boolean matched = matches(patt, i); if (matched) { for (int j = 0; j < this.excludedPatterns.length; j++) { boolean excluded = matchesExclusion(patt, j); if(excluded) { return false; } } return true; } } return false; }
在JDKRegexpMethodPointcut中通过JDK中的正则表达式匹配来完成pointcut的最终确定:
- protected boolean matches(String pattern, int patternIndex) {
- Matcher matcher = this .compiledPatterns[patternIndex].matcher(pattern);
- return matcher.matches();
- }
protected boolean matches(String pattern, int patternIndex) { Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern); return matcher.matches(); }
Advisor:
当我们完成额外的动作设计(advice)和额外动作插入点的设计(pointcut)以后,我们需要一个对象把他们
结合起来,这就是通知器 -
advisor,定义应该在哪里应用哪个通知。Advisor的实现有:DefaultPointcutAdvisor他有两个属性advice和
pointcut来让我们配置advice和pointcut。
接着我们就可以通过ProxyFactoryBean来配置我们的代理对象和方
面行为,在ProxyFactoryBean中有interceptorNames来配置已经定义好的通知器-advisor,虽然这里的名字叫做
interceptNames,但实际上是供我们配置advisor的地方,具体的代理实现通过JDK
的Proxy或者CGLIB来完成。因为ProxyFactoryBean是一个FactoryBean,在ProxyFactoryBean中我们通过
getObject()可以直接得到代理对象:
- public Object getObject() throws BeansException {
- //这里初始化通知器链
- initializeAdvisorChain();
- if (isSingleton()) {
- //根据定义需要生成单件的Proxy
- return getSingletonInstance();
- }
- else {
- .......
- //这里根据定义需要生成Prototype类型的 Proxy
- return newPrototypeInstance();
- }
- }
public Object getObject() throws BeansException { //这里初始化通知器链 initializeAdvisorChain(); if (isSingleton()) { //根据定义需要生成单件的Proxy return getSingletonInstance(); } else { ....... //这里根据定义需要生成Prototype类型的Proxy return newPrototypeInstance(); } }
我们看看怎样生成单件的代理对象:
- private synchronized Object getSingletonInstance() {
- if ( this .singletonInstance == null ) {
- this .targetSource = freshTargetSource();
- if ( this .autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
- // 这里设置代理对象的接口
- setInterfaces(ClassUtils.getAllInterfacesForClass( this .targetSource.getTargetClass()));
- }
- // Eagerly initialize the shared singleton instance.
- super .setFrozen( this .freezeProxy);
- // 注意这里的方法会使用ProxyFactory 来生成我们需要的Proxy
- this .singletonInstance = getProxy(createAopProxy());
- // We must listen to superclass advice change events to recache the singleton
- // instance if necessary.
- addListener( this );
- }
- return this .singletonInstance;
- }
- //使用createAopProxy放回的AopProxy来得到代理对象。
- protected Object getProxy(AopProxy aopProxy) {
- return aopProxy.getProxy( this .beanClassLoader);
- }
private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // 这里设置代理对象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(this.targetSource.getTargetClass())); } // Eagerly initialize the shared singleton instance. super.setFrozen(this.freezeProxy); // 注意这里的方法会使用ProxyFactory来生成我们需要的Proxy this.singletonInstance = getProxy(createAopProxy()); // We must listen to superclass advice change events to recache the singleton // instance if necessary. addListener(this); } return this.singletonInstance; } //使用createAopProxy放回的AopProxy来得到代理对象。 protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.beanClassLoader); }
ProxyFactoryBean的父类是AdvisedSupport,Spring使用AopProxy接口把AOP代理的实现与框架的其他
部分分离开来;在AdvisedSupport中通过这样的方式来得到AopProxy,当然这里需要得到AopProxyFactory的帮助 -
下面我们看到Spring为我们提供的实现,来帮助我们方便的从JDK或者cglib中得到我们想要的代理对象:
- protected synchronized AopProxy createAopProxy() {
- if (! this .isActive) {
- activate();
- }
- return getAopProxyFactory().createAopProxy( this );
- }
protected synchronized AopProxy createAopProxy() { if (!this.isActive) { activate(); } return getAopProxyFactory().createAopProxy(this); }
而在ProxyConfig中对使用的AopProxyFactory做了定义:
- //这个DefaultAopProxyFactory是Spring用来生成 AopProxy的地方,
- //当然了它包含JDK和Cglib两种实现方式。
- private transient AopProxyFactory aopProxyFactory = new DefaultAopProxyFactory();
//这个DefaultAopProxyFactory是Spring用来生成AopProxy的地方, //当然了它包含JDK和Cglib两种实现方式。 private transient AopProxyFactory aopProxyFactory = new DefaultAopProxyFactory();
其中在DefaultAopProxyFactory中是这样生成AopProxy的:
- public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException {
- //首先考虑使用cglib来实现代理对象,当然如果同时目标 对象不是接口的实现类的话
- if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() ||
- advisedSupport.getProxiedInterfaces().length == 0 ) {
- //这里判断如果不存在cglib库,直接抛出异常。
- if (!cglibAvailable) {
- throw new AopConfigException(
- "Cannot proxy target class because CGLIB2 is not available. " +
- "Add CGLIB to the class path or specify proxy interfaces." );
- }
- // 这里使用Cglib来生成Proxy,如果 target不是接口的实现的话,返回cglib类型的AopProxy
- return CglibProxyFactory.createCglibProxy(advisedSupport);
- }
- else {
- // 这里使用JDK来生成Proxy,返回JDK类 型的AopProxy
- return new JdkDynamicAopProxy(advisedSupport);
- }
- }
public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException { //首先考虑使用cglib来实现代理对象,当然如果同时目标对象不是接口的实现类的话 if (advisedSupport.isOptimize() || advisedSupport.isProxyTargetClass() || advisedSupport.getProxiedInterfaces().length == 0) { //这里判断如果不存在cglib库,直接抛出异常。 if (!cglibAvailable) { throw new AopConfigException( "Cannot proxy target class because CGLIB2 is not available. " + "Add CGLIB to the class path or specify proxy interfaces."); } // 这里使用Cglib来生成Proxy,如果target不是接口的实现的话,返回cglib类型的AopProxy return CglibProxyFactory.createCglibProxy(advisedSupport); } else { // 这里使用JDK来生成Proxy,返回JDK类型的AopProxy return new JdkDynamicAopProxy(advisedSupport); } }
于是我们就可以看到其中的代理对象可以由JDK或者Cglib来生成,我们看到JdkDynamicAopProxy类和
Cglib2AopProxy都实现的是AopProxy的接口,在JdkDynamicAopProxy实现中我们可以看到Proxy是怎样生成的:
- public Object getProxy(ClassLoader classLoader) {
- if (logger.isDebugEnabled()) {
- Class targetClass = this .advised.getTargetSource().getTargetClass();
- logger.debug( "Creating JDK dynamic proxy" +
- (targetClass != null ? " for [" + targetClass.getName() + "]" : "" ));
- }
- Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces( this .advised);
- findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
- //这里我们调用JDK Proxy来生成需要的Proxy实 例
- return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this );
- }
public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { Class targetClass = this.advised.getTargetSource().getTargetClass(); logger.debug("Creating JDK dynamic proxy" + (targetClass != null ? " for [" + targetClass.getName() + "]" : "")); } Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); //这里我们调用JDK Proxy来生成需要的Proxy实例 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
这样用Proxy包装target之后,通过ProxyFactoryBean得到对其方法的调用就被Proxy拦截了,
ProxyFactoryBean的getObject()方法得到的实际上是一个Proxy了,我们的target对象已经被封装了。对
ProxyFactoryBean这个工厂bean而言,其生产出来的对象是封装了目标对象的代理对象。
发表评论
-
Spring--quartz中cronExpression配置说明
2011-12-02 18:28 0quartz中cronExpression配置说明 字段 ... -
使用Spring的jdbcTemplate进一步简化JDBC操作
2011-12-02 09:20 1263先看applicationContext.xml配置文件: ... -
Spring MVC:使用SimpleUrlHandlerMapping的一个简单例子
2011-12-01 11:26 966实现一个控制器ShirdrnCon ... -
最简单的Spring MVC入门示例
2010-05-19 14:29 1528应一位朋友的要求,写一个最简单的spring示例,使用s ... -
Spring源代码解析(十):Spring Acegi框架授权的实现
2010-03-18 12:48 1523我们从FilterSecurityIntercep ... -
Spring源代码解析(九):Spring Acegi框架鉴权的实现
2010-03-18 12:47 1506简单分析一下Spring Acegi的源代码实现: Ser ... -
Spring源代码解析(八):Spring驱动Hibernate的实现
2010-03-18 12:41 1446O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spri ... -
Spring源代码解析(七):Spring AOP中对拦截器调用的实现
2010-03-18 12:40 1420前面我们分析了Spring AOP实现中得到Proxy对象的过 ... -
Spring源代码解析(六):Spring声明式事务处理
2010-03-18 12:37 1097我们看看Spring中的事务处理的代码,使用Spring管理事 ... -
Spring源代码解析(四):Spring MVC
2010-03-18 12:35 7740下面我们对Spring MVC框架代码进行分析,对于web ... -
Spring源代码解析(三):Spring JDBC
2010-03-18 12:33 1697下面我们看看Spring JDBC相关的实现, 在Spri ... -
Spring源代码解析(二):IoC容器在Web容器中的启动
2010-03-18 12:32 1447上面我们分析了IOC容器本身的实现,下面我们看看在典型的web ... -
Spring源代码解析(一):IOC容器
2010-03-18 12:30 2671在Spring中,IOC容器的重要地位我们就不多说了,对于Sp ... -
使用Spring的JdbcTemplate和BeanPropertyRowMapper完成的JDBC
2010-03-18 12:08 2248先道要加上两个包:Spring2.5下面的: spring. ... -
使用Spring的SimpleJdbcTemplate完成DAO操作
2010-03-18 12:06 1510l SimpleJdbcTemplate内部包含了 ... -
使用Spring的NamedParameterJdbcTemplate完成DAO操作
2010-03-18 12:05 1426NamedParameterJdbcTemplate内部包含了 ... -
Spring in Action 学习笔记—第四章 征服数据库(转)
2010-03-18 12:03 1253Spring2.0正式版(http://www.springf ... -
Spring管理JDBC连接
2010-03-18 11:59 1690在Spring中,JdbcTemplate是经常被使用的类来帮 ... -
Spring JDBC数据库操作类
2010-03-18 09:26 16441.JdbcTemplate 在Spring中, ... -
Spring JdbcTemplate 批量插入或更新操作
2010-03-18 09:19 5278用 JdbcTemplate 进行批量插入或更新操作 ...
相关推荐
Spring源代码解析5:Spring AOP获取Proxy .doc Spring源代码解析6:Spring声明式事务处理 .doc Spring源代码解析7:Spring AOP中对拦截器调用的实现 .doc Spring源代码解析8:Spring驱动Hibernate的实现.doc Spring...
Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代码解析9:...
Spring源代码解析(五):Spring AOP获取Proxy Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源...
本文将深入解析Spring AOP如何获取代理对象,即Proxy。 首先,我们需要理解AOP的核心概念: 1. **Advice**:通知,是切面实际执行的操作。在Spring中,Advice可以是Before、AfterReturning、AfterThrowing以及...
Spring源代码解析5:Spring AOP获取Proxy;Spring源代码解析6:Spring声明式事务处理 ; Spring源代码解析7:Spring AOP中对拦截器调用的实现 Spring源代码解析8:Spring驱动Hibernate的实现;Spring源代
Spring源代码解析(五):Spring AOP获取Proxy.doc Spring源代码解析(六):Spring声明式事务处理.doc Spring源代码解析(七):Spring AOP中对拦截器调用的实现.doc Spring源代码解析(八):Spring驱动Hibernate的...
"spring源代码解析(五):spring AOP获得proxy.doc"和"spring源代码解析(七):spring AOP中对拦截器调用的实现.doc"详细解释了AOP代理的生成过程,以及Aspect的实现和通知的执行流程。 5. **事务管理**:"spring...
本文将详细解析Spring AOP如何利用这两个组件来实现拦截器链的调用。 首先,Spring在生成代理对象时,会使用`Proxy.newProxyInstance()`方法,这个方法需要三个参数:类加载器、被代理对象实现的接口列表以及一个...
《Spring源代码分析:AOP的实现》 在软件开发领域,Spring框架因其强大的功能和易用性,已经成为Java企业级应用的事实标准。其中,面向切面编程(Aspect Oriented Programming,简称AOP)是Spring的重要特性之一,...
接下来,我们将深入探讨Spring 4中的AOP概念、实现机制以及源代码解析。 **AOP概念** 1. **切面(Aspect)**:切面是关注点的模块化,它将一组相关或相互关联的功能封装在一起,可以看作是跨越多个对象的行为或责任...
pring源代码各个模块作用 核心模块: 1 spring-core:核心模块 依赖注入IOC和DI的最基本实现 spring-beans:Bean工厂与装配 spring-context:上下文,即IOC容器 spring-context-support:对IOC的扩展,以及IOC子容器 ...
Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。这个"spring aop jar 包"包含了实现这一功能所需的类和接口,...
标题中的“spring-aop”指的是Spring框架中的面向切面编程(Aspect-Oriented Programming, AOP)模块,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的核心概念包括切面(Aspect)、通知...
`org.springframework.aop`包包含了AOP的实现,如`Advisor`、`Pointcut`和`Proxy`等概念。 3. **IoC容器**:Spring的IoC容器负责管理应用的对象及其依赖。在`src`中,`BeanFactory`是IoC容器的基础,而`...
5. **引入(Introduction)**:引入允许我们在现有类中添加新的方法和属性,无需修改源代码。 6. **目标(Target)**:目标对象是指被通知的对象,即切面关注的业务逻辑对象。 7. **代理(Proxy)**:代理是AOP的实现...
源代码是理解任何软件系统内部运作的关键,对于Spring框架而言,通过阅读源码,我们可以深入理解其设计理念和实现机制。 在Spring框架的源代码中,有几个关键部分值得我们关注: 1. **IoC容器**:这是Spring的核心...
在Spring源代码中,我们可以看到以下几个关键组件: 1. **IoC容器**:IoC(Inversion of Control,控制反转)是Spring的核心,它负责管理对象的生命周期和对象间的依赖关系。在源代码中,`org.springframework....
本文将深入探讨如何使用Spring的IOC和DI特性,结合动态代理(Dynamic Proxy)来实现一种类似AOP(面向切面编程)的功能,以达到在不修改原有代码的情况下增强或拦截方法调用的目的。 **一、Spring IOC(控制反转)*...
Spring AOP(面向切面编程)是Spring框架中的一个重要组件,它允许我们在不修改源代码的情况下,通过在程序运行时动态地将代码插入到方法调用中,来实现跨切面的关注点,如日志记录、性能监控、事务管理等。而Spring...