这两天一直在读spring1.2的AOP实现源码,AOP实现原理说起来很简单,对于实现业务接口的对象使用java代理机制实现,而对于一般的类使用cglib库实现,但spring的实现还是比较复杂的,不过抓住了本质去看代码就容易多了。发现一篇04年写的
《spring源码分析:实现AOP》,倒是不用自己再写了,04年的时候已经有很多人研读过spring的源码,而那时的我还在学校,对java半懂不懂的状态,就算到现在也不敢说真的懂了,继续学习、努力。文章如下:
我的问题
为了完成公司应用开发平台的设计,这几天一直在研究Spring的扩展机制。Spring的核心无疑是BeanFactory,
ApplicationContext和AOP。在“Spring
AOP编程”教程的例子中,是由ProxyFactoryBean来实现的。问题来了,普通的bean和FactoryBean的配置完全是一样的。那
么,BeanFactory是如何区分普通的Bean和用作Proxy的FactoryBean的?ProxyFactoryBean又是怎样实现AOP
功能的?(本文还很不完善,我会继续修改。)
FactoryBean的职责
FactoryBean在Spring中被当成一种特殊的bean,通过实现FactoryBean接口进行扩展。FactoryBean的职责是:
l.封装了创建对象或查找对象的逻辑。
2.提供了一个中间层,用于支持AOP。
我们来看一个LocalStatelessSessionProxyFactoryBean的例子。首先,定义Stateless EJB的代理,id为ejbServiceProxy:
<bean id="ejbServiceProxy" class="LocalStatelessSessionProxyFactoryBean">
<property name="jndiName">
<value>myEjb</value>
</property>
<property name="businessInterface">
<value>com.mycompany.MyBusinessInterface</value>
</property>
</bean>
然后,再将这个业务逻辑服务对象注入客户程序:
<bean id="myAction" class = "samples.myAction">
<property name="myService">
<ref bean="ejbServiceProxy"/>
</property>
</bean>
这样,客户程序并不知道myService的实现细节,Spring使用FactoryBean完成了两者之间的解耦。
准备代码分析环境
1. 安装Eclipse和Spring IDE。
2. 下载Spring framework源代码,并导入Eclipse。
3. 在类路径创建log4j.properties配置文件,设置如下:
log4j.rootLogger=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{SSS} %p %c{2} - %m%n
4. 编写TestCase,跟踪Console窗口的debug信息。
FactoryBean源代码分析
如果bean实现了FactoryBean接口,BeanFactory将把它作为一个bean工厂,而不是直接作为普通的bean。正常情况下,
BeanFactory的getBean("bean")返回FactoryBean生产的bean实例,如果要返回FactoryBean本身的实例,
使用getBean("&bean")的调用方式。
在分析ProxyFactoryBean之前,我们先分析BeanFactory,它是Spring Framework的基础。我们看看它是如何分别处理普通的Bean和FactoryBean的。
BeanFactory分析
BeanFactory类图
如以上的类图所示,XmlBeanFactory继承了AbstactBeanFactory抽象类。AbstactBeanFactory类中使用了
Template
Method设计模式,其中的模板方法为getBeanDefinition()和createBean()两个抽象方法。其中
AbstractAutowireCapableBeanFactory类实现了getBeanDefinition()方法,
DefaultAutowireCapableBeanFactory类实现了getBeanDefinition()方法。当调用getBean()方
法时,AbstractBeanFactory类定义的逻辑分别调用了这两个模板方法。
BeanFactory类的调用顺序
我们暂时不使用ApplicationContext,以简化分析过程。我在这里使用了“Spring AOP编程”的例子,请参照该教程阅读。首先,编写测试用例,代码如下:
public class AopTest extends TestCase {
XmlBeanFactory factory = null;
protected void setUp() throws Exception {
super.setUp();
InputStream is = new FileInputStream("testaop.xml");
factory = new XmlBeanFactory(is);
}
public void testGetBean() {
Bean bean = (Bean)factory.getBean("bean");
assertNotNull(bean);
bean.theMethod();
}
}
1. 首先,XmlBeanFactory使用XmlBeanDefinitionReader读入testaop.xml配置文件,后者用
XmlBeanDefinitionParser和DefaultXmlBeanDefinitionParser进行分析,从中得到
BeanDefinition的信息,并保存在XmlBeanDefinitionReader的BeanDefinitionRegistry变量里。
2. 客户程序调用getBean方法时,AbstractBeanFactory首先使用transFormedBeanName方法分析传入的Bean名称,判断客户程序需要FactoryBean本身,还是它所创建的Bean对象。
3. 接下来,如果bean被定义为singleton模式,AbstractBeanFactory调用createBean方法根据
BeanDefinition信息实例化bean类,然后将该bean实例传给getObjectForSharedInstance方法并返回
getObjectForSharedInstance的返回对象。GetObjectForSharedInstance方法摘要如类图所示,首先判断
bean是否继承了FactoryBean。如果是,返回FactoryBean的getObject方法(下节我将详细分析使用
ProxyFactoryBean如何实现AOP);如果不是,返回bean对象。
4. 如果bean被定义为prototype模式,每次客户程序请求都会生成新的bean实例,因此,createBean方法直接实例化bean对象并返回。
ProxyFactoryBean如何实现AOP
ProxyFactoryBean类图
FactoryBean接口如下图所示,共有三个方法getObject,getObjectType,和isSingleton。ProxyFactoryBean实现了FactoryBean接口,它的相关类图如下:
实现AOP的过程
如上图所示,ProxyFactoryBean类继承了AdvisedSupport类,后者继承了ProxyConfig类并定义了操作advisor
和interceptor的接口,以支持AOP。当BeanFactory实例化ProxyFactoryBean时,根据配置文件的定义将关于
advice,pointcut,advisor,所代理的接口和接口实现类的所有信息传给ProxyFactoryBean。
当客户程序调用BeanFactory的getBean方法时,ProxyFactory使用JdkDynamicAopProxy实例化
BeanImpl类,并用JdkDynamicAopProxy的invoke方法执行advice。至于执行advice的时机,由
ProxyFactoryBean调用RegexpMethodPointcutAdvisor进行判断。
分享到:
相关推荐
AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析-SpringAOP中定义的类图AOP流程源码分析...
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 Spring源代码解析(十):Spring Acegi框架授权...
Maven坐标:org.springframework:spring-aop:5.0.10.RELEASE; 标签:spring、aop、springframework、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览...
Java流行框架源码分析:Spring源码、SpringBoot源码、SpringAOP源码、SpringSecurity源码、SpringSecurity OAuth2源码、JDK源码、Netty源码
Spring基础:Spring AOP简单使用
Spring源码最难问题:当Spring AOP遇上循环依赖.docx
使用Spring的注解方式实现AOP的细节
NULL 博文链接:https://ylxy3058.iteye.com/blog/2224244
hualinux spring XML开发系列之 hualinux spring 3.15:Spring AOP 文字版本
When to use Spring AOP and AspectJ AOP? Expert author Ramnivas Laddad shows how to combine technologies such as Spring, Hibernate, Swing, and JDBC with AspectJ. The book fully covers the latest ...
Maven坐标:org.springframework:spring-aop:5.2.0.RELEASE; 标签:springframework、spring、aop、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 ...
你不仅能从本书中参透Spring框架的出色架构和设计思想,还能从Spring优雅的实现源码中一窥Java语言的精髓。本书在开篇之前对Spring的设计理念和整体架构进行了全面的介绍,能让读者从宏观上厘清Spring各个功能模块...
功能:实现AOP中异常日志管理的类
Spring mvc mybatis plus 实现AOP 切面日志系统,带有数据库。可以自行拓展
Spring源代码解析(七):Spring AOP中对拦截器调用的实现 8. Spring源代码解析(八):Spring驱动Hibernate的实现 9.Spring源代码解析(九):Spring Acegi框架鉴权的实现 10. Spring源代码解析(十):Spring ...
NULL 博文链接:https://shmilyaw-hotmail-com.iteye.com/blog/2430730
Spring-Aop源码实现
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
第三章:Spring AOP API 设计与实现小马哥(mercyblitz)Spring AOP API 设计与实现Spring AOP API 整体设计接入
第四章:Spring AOP 设计模式小马哥(mercyblitz)Spring AOP 设计模式抽象工厂模式(Abstract factory)实现构建器模式