自我分析-Spring AOP
来源:互联网 发布:免费发布网络推广平台 编辑:程序博客网 时间:2024/04/28 01:57
Spring AOP直白的来说就是使用了JDK的动态代理和CGLIB对Bean的代理,从而实现方法增强的效果。
注意:
1.分析框架代码时,要常使用类继承、调用关系等快捷键,可以更高效的学习,快捷键可以设置成你习惯的按键;
2.本文重在怎么自我分析框架代码,所以对其中解析需自己实际跟踪代码实践方可;
3.spring源代码版本 spring-framework-3.2.1.RELEASE。
预览
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory,自动装箱BeanFactory。
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator,代理对象创建类。
org.springframework.aop.framework.JdkDynamicAopProxy,JDK动态代理类。
org.springframework.aop.framework.CglibAopProxy,CGLIB动态代理类。
入口-createBean
前面我们分析Spring IOC时,了解了IOC的资源定位、加载、注册等步骤,但是对于AOP的实现还未分析。
还记得createBean嘛,这里就是实际创建Bean的入口,在getBean中调用了。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
public <T> T createBean(Class<T> beanClass) throws BeansException {// Use prototype bean definition, to avoid registering bean as dependent bean.RootBeanDefinition bd = new RootBeanDefinition(beanClass);bd.setScope(SCOPE_PROTOTYPE);bd.allowCaching = false;return (T) createBean(beanClass.getName(), bd, null);}
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {if (logger.isDebugEnabled()) {logger.debug("Creating instance of bean '" + beanName + "'");}// Make sure bean class is actually resolved at this point.resolveBeanClass(mbd, beanName);// Prepare method overrides.try {mbd.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 产生 AOP 代理对象的入口Object bean = resolveBeforeInstantiation(beanName, mbd);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}Object beanInstance = doCreateBean(beanName, mbd, args);if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}
对象实例化前处理
在对象实例化前做相应的逻辑处理,即是否需创建代理对象
protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName)throws BeansException {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;// 在对象实例化前的处理操作Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}
在实例化前会判断是否存在AOP的代理,而此方法的实现在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator。
<strong></strong>public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {Object cacheKey = getCacheKey(beanClass, beanName);if (beanName == null || !this.targetSourcedBeans.containsKey(beanName)) {if (this.advisedBeans.containsKey(cacheKey)) {return null;}if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}// Create proxy here if we have a custom TargetSource.// Suppresses unnecessary default instantiation of the target bean:// The TargetSource will handle target instances in a custom fashion.if (beanName != null) {TargetSource targetSource = getCustomTargetSource(beanClass, beanName);if (targetSource != null) {this.targetSourcedBeans.put(beanName, Boolean.TRUE);// 获取通知点即需增强效果的接口,如想了解可查看其子类AbstractAdvisorAutoProxyCreatorObject[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);// 根据类名、需增强接口等信息创建代理对象Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());return proxy;}}return null;}
生产代理对象的准备工作
接下来将看到一系列的准备工作:代理工厂、目标对象的接口、目标对象的通知者等。
<span style="white-space:pre"></span>protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {ProxyFactory proxyFactory = new ProxyFactory();// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.proxyFactory.copyFrom(this);if (!shouldProxyTargetClass(beanClass, beanName)) {// 获取所有目标对象的接口Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);for (Class<?> targetInterface : targetInterfaces) {proxyFactory.addInterface(targetInterface);}}// 通过通知点即类名创建通知者(切入点及增强效果的集合)Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);for (Advisor advisor : advisors) {proxyFactory.addAdvisor(advisor);}proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}// 通过工厂和proxyClassLoader来获取代理对象return proxyFactory.getProxy(this.proxyClassLoader);}
创建JDK动态代理 OR CGLIB
<span style="white-space:pre"></span>public Object getProxy(ClassLoader classLoader) {return createAopProxy().getProxy(classLoader); //使用}
此处的createAopProxy(),是使用org.springframework.aop.framework.DefaultAopProxyFactory中的createAopProxy来
创建JdkDynamicAopProxy还是CglibProxyFactory。
其中JDK的动态代理只能对接口型的目标对象进行代理,而CGLIB没有此限制,代码中我们可以明确的看到。
<span style="white-space:pre"></span>public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {Class targetClass = config.getTargetClass();if (targetClass == null) {throw new AopConfigException("TargetSource cannot determine target class: " +"Either an interface or a target is required for proxy creation.");}if (targetClass.isInterface()) { // 目标对象若是接口,即生产JDK的动态代理return new JdkDynamicAopProxy(config);}return CglibProxyFactory.createCglibProxy(config); // 非接口型目标对象,即使用CGLIB来实现代理。}else {return new JdkDynamicAopProxy(config);}}
接下来就是的getProxy生产代理对象就要看JdkDynamicAopProxy和CglibProxyFactory两个类了,若对两者的动态代理不熟悉,先实现了解下,
再接着分析。
JDK动态代理:http://blog.csdn.net/xiaohai0504/article/details/6884925
CGLIB动态代理:http://blog.csdn.net/xiaohai0504/article/details/6832990
- 自我分析-Spring AOP
- 自我分析-Spring IOC
- Spring AOP中自我调用的问题
- Spring AOP和事务处理的自我总结
- spring aop源码分析
- Spring AOP 深入分析
- Spring Aop源码分析
- spring aop 原理分析
- spring aop 源码分析
- Spring源码分析:实现AOP- -
- Spring Aop技术原理分析
- Spring实现AOP源码分析
- Spring AOP 原理分析 part1
- spring源码分析之aop
- 理解Spring AOP 原理(三)Spring AOP 源码分析
- Spring源码分析-深入浅出AOP(图文分析)
- Spring源码分析----AOP通知以及编程式AOP
- Spring AOP介绍及源码分析
- POJ 1389 Area of Simple Polygons(多矩形重叠面积==离散化)
- IOS流媒体播放
- 【debug】googlecode 使用代理svn下载代码
- UFT 11.5 /12.1 汉化以及视频教程下载(附免费VBS视频教程),全互联网首发
- 包装类
- 自我分析-Spring AOP
- 关于Sql Server数据库中的事务如何处理
- Linux命令--ln
- Linux 脚本编写基础
- 条款27:要求/禁止对象产生于heap中
- cookie session sessionid jsessionid
- nfs:server 192.168.0.111 not responding,still trying问题解决方法
- 生产安全加固脚本
- ST、SC、FC、LC光纤接头区别