`

Spring AOP实现逻辑源码分析总结

阅读更多

AspectJAutoProxyRegistrar 根据@EnableAspectJAutoProxy或<aop:aspectj-autoproxy/>注册AnnotationAwareAspectJAutoProxyCreator

 

AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator

DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator

AbstractAdvisorAutoProxyCreator extends SmartInstantiationAwareBeanPostProcessor

 

AbstractAdvisorAutoProxyCreator->getAdvicesAndAdvisorsForBean;findEligibleAdvisors;findCandidateAdvisors;

ReflectiveAspectJAdvisorFactory

BeanFactoryAspectJAdvisorsBuilder->buildAspectJAdvisors

MetadataAwareAspectInstanceFactory BeanFactoryAspectInstanceFactory;

InstantiationModelAwarePointcutAdvisorImpl

 

AspectJPointcutAdvisor使用AspectJAroundAdvice作为参数,其中SimpleBeanFactoryAwareAspectInstanceFactory是AspectInstanceFactory在解析xml创建advice的实现类。

AspectJExpressionPointcut

AspectJAroundAdvice or MethodInterceptor

 

$$$bean创建时会被代理,在AbstractAutoProxyCreator中,创建bean之前会调用所有advisor的getPointCut,来匹配bean的类和方法

 

 

 

TargetSource应用说明:TargetSource Developers using Spring AOP don’t normally need to work directly with TargetSources, but this provides a powerful means of supporting pooling, hot swappable and other sophisticated targets.The org.springframework.aop.target.HotSwappableTargetSource exists to allow the target of an AOP proxy to be switched while allowing callers to keep their references to it. 能够实现热加载,热交换bean。

 

 

ApplicationContext加载生成过程参见AbstractApplicationContext.refresh方法。

1、obtainFreshBeanFactory创建DefaultListableBeanFactory作为beanFactory

2、obtainFreshBeanFactory加载xml,生成BeanDefinition(GenericBeanDefinition??)

3、prepareBeanFactory配置beanFactory的属性,比如添加BeanPostProcessor->LoadTimeWeaverAwareProcessor

4、postProcessBeanFactory添加ApplicationContext子类独有的BeanPostProcessor

5、invokeBeanFactoryPostProcessors调用BeanFactoryPostProcessor,首先调用BeanDefinitionRegistryPostProcessor类型的,然后调用其他类型的.其中ConfigurationClassPostProcessor是其子类,用来处理@Configuration classes,在xml中声明<context:annotation-config/> or <context:component-scan/>时生成beandefinition。

6、registerBeanPostProcessors生成常规的BeanPostProcessor的实例,并添加到BeanPostProcessor列表

7、initMessageSource

8、initApplicationEventMulticaster

9、onRefresh

10、registerListeners

11、finishBeanFactoryInitialization,Instantiate all remaining (non-lazy-init) singletons初始化所有singletons bean(not-lazy),生成bean的过程(loadclass->preconstruct->new instance->postconstruct->set properties->bean post process->initialize)

12、finishRefresh

 

 

B1、BeanPostProcess与依赖的说明:

BeanPostProcessors and AOP auto-proxying

Classes that implement the BeanPostProcessor interface are special and are treated differently

by the container. All BeanPostProcessors and beans that they reference directly are

instantiated on startup, as part of the special startup phase of the ApplicationContext. Next,

all BeanPostProcessors are registered in a sorted fashion and applied to all further beans in the

container. Because AOP auto-proxying is implemented as a BeanPostProcessor itself, neither

BeanPostProcessors nor the beans they reference directly are eligible for auto-proxying, and

thus do not have aspects woven into them.

For any such bean, you should see an informational log message: "Bean foo is not eligible

for getting processed by all BeanPostProcessor interfaces (for example: not eligible for autoproxying)".

Note that if you have beans wired into your BeanPostProcessor using autowiring or

@Resource (which may fall back to autowiring), Spring might access unexpected beans when

searching for type-matching dependency candidates, and therefore make them ineligible for

auto-proxying or other kinds of bean post-processing. For example, if you have a dependency

annotated with @Resource where the field/setter name does not directly correspond to the

declared name of a bean and no name attribute is used, then Spring will access other beans for

matching them by type.

 

B2、BeanFactoryPostProcessor的说明:

If you want to change the actual bean instances (i.e., the objects that are created from the

configuration metadata), then you instead need to use a BeanPostProcessor (described

above in the section called “Customizing beans using a BeanPostProcessor”). While it is

technically possible to work with bean instances within a BeanFactoryPostProcessor (e.g.,

using BeanFactory.getBean()), doing so causes premature bean instantiation, violating the

standard container lifecycle. This may cause negative side effects such as bypassing bean post

processing.

Also, BeanFactoryPostProcessors are scoped per-container. This is only relevant if you are

using container hierarchies. If you define a BeanFactoryPostProcessor in one container, it

will only be applied to the bean definitions in that container. Bean definitions in one container

will not be post-processed by BeanFactoryPostProcessors in another container, even if both

containers are part of the same hierarchy.

 

B2.1、PropertyPlaceholderConfigurer是个BeanFactoryPostProcessor,获取.properties文件的内容并替换BeanDefinition,其中<context:property-placeholder location="classpath:com/foo/jdbc.properties"/>标签与<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="locations" value="classpath:com/foo/jdbc.properties"/></bean>效果相同

 

B3、Annotation injection is performed before XML injection, thus the latter configuration will override

the former for properties wired through both approaches.

 

B4、<context:annotation-config/> The implicitly registered post-processors include AutowiredAnnotationBeanPostProcessor,

CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor, as

well as the aforementioned RequiredAnnotationBeanPostProcessor.注册多个beanpostprocessors。注意:<context:annotation-config/> only looks for annotations on beans in the same applicationcontext in which it is defined。比如dispatcher和service 的两个context.

The use of <context:component-scan> implicitly enables the functionality of <context:annotation-config>. There is usually no need to include the<context:annotation-config> element when using <context:component-scan>.

Furthermore, the AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor are both included implicitly when you use the componentscan element. That means that the two components are autodetected and wired together - all without any bean configuration metadata provided in XML.

 

B5、EnableLoadTimeWeaving与<context:load-time-weaver/>作用相同。

EnableAspectJAutoProxy与<aop:aspectj-autoproxy/>作用相同。注册自动代理创建者AnnotationAwareAspectJAutoProxyCreator。切面bean仍旧需要在xml中定义,spring检测bean是否具有@aspect注解。

除了使用@aspect注解外,也可以通过xml的方式生成切面,<aop:config>标签会在ConfigBeanDefinitionParser->configureAutoProxyCreator函数中生效。Within your Spring configurations, all aspect and advisor elements must be placed within an

<aop:config> element (you can have more than one <aop:config> element in an application

context configuration). An <aop:config> element can contain pointcut, advisor, and aspect elements

(note these must be declared in that order).Warning

The <aop:config> style of configuration makes heavy use of Spring’s auto-proxying

mechanism. This can cause issues (such as advice not being woven) if you are already

using explicit auto-proxying via the use of BeanNameAutoProxyCreator or suchlike. The

recommended usage pattern is to use either just the <aop:config> style, or just the

AutoProxyCreator style.

<aop:config proxy-target-class="true">

<!-- other beans defined here... -->

</aop:config>

<aop:aspectj-autoproxy proxy-target-class="true"/>

 

说明:To be clear: using 'proxy-target-class="true"' on <tx:annotation-driven/>,

<aop:aspectj-autoproxy/> or <aop:config/> elements will force the use of CGLIB

proxies for all three of them.

 

B6、容器外对象注入。缺省情况下的容器外对象注入,该容器外对象虽然是被创建的却不能被代理。

@EnableSpringConfigured和<context:spring-configured/>作用相同,都是扫描@Configurable,比如@Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true)

这种注入要求在容器内有prototype的bean,定义,而且和@Configurable("name")相同,由于要依赖AnnotationBeanConfigurerAspect,所以

<bean id="myService"

class="com.xzy.myapp.service.MyService"

depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect">。除了以上配置,需要LoadTimeWeaver织入AnnotationBeanConfigurerAspect。javaagent和instrument是需要的。

 

B7、NamespaceHandler是来处理xml中的命名空间的处理器,通过不同的handler,处理不同的element。AopNamespaceHandler专门用来处理namespace=aop的element,比如aop:config,aop:aspectj-autoproxy,aop:scoped-proxy。

 

B8、11.8 Manipulating advised objects

However you create AOP proxies, you can manipulate them using the org.springframework.aop.framework.Advised interface. Any AOP proxy can be cast to this

interface, whichever other interfaces it implements.

 

B9、关于bean的实例化与BeanFactory的getBean方法,都在AbstractBeanFactory类中实现,getBean 委托给doGetBean,按名字创建实例,然后给getObjectForBeanInstance处理。

getObjectForBeanInstance首先看需要的是FactoryBean,还是FactoryBean生产的bean.如果是一个isSynthetic的bean,则不进行post-processing。

什么是synthetic的bean呢.spring 注释 Set whether this bean definition is 'synthetic', that is, not defined by the application itself (for example, an infrastructure bean such as a helper for auto-proxying, created through {@code <aop:config>}

 

B10、spring获取资源的方式。使用PathMatchingResourcePatternResolver解析location返回Resource,支持classpath:,classpath*:,file:,jar:

没有通配符的情况No Wildcards: 

In the simple case, if the specified location path does not start with the "classpath*:" prefix, and does not contain a PathMatcher pattern, 

this resolver will simply return a single resource via a getResource() call on the underlying ResourceLoader. 

Examples are real URLs such as "file:C:/context.xml", pseudo-URLs such as "classpath:/context.xml", and simple unprefixed paths such as "/WEB-INF/context.xml". 

The latter will resolve in a fashion specific to the underlying ResourceLoader (e.g. ServletContextResource for a WebApplicationContext). 

 

Ant风格的Ant-style Patterns: 

When the path location contains an Ant-style pattern, e.g.: 

 /WEB-INF/*-context.xml

 com/mycompany/**/applicationContext.xml

 file:C:/some/path/*-context.xml

 classpath:com/mycompany/**/applicationContext.xml

 

classpath*: Prefix: 

There is special support for retrieving multiple class path resources with the same name, via the "classpath*:" prefix. 

For example, "classpath*:META-INF/beans.xml" will find all "beans.xml" files in the class path, be it in "classes" directories or in JAR files. 

This is particularly useful for autodetecting config files of the same name at the same location within each jar file. Internally, this happens via a ClassLoader.getResources() call, and is completely portable. 

注意:如果使用了classpath*:*.xml ,则不会得到jar根目录下的资源文件。

classpath 只会到classes目录下去查找资源,classpath*:会包括jar的文件

 

B11、spring的类型自动转换。相关的类包括BeanWapper,TypeConverterDelegate,ResourceEditorRegistrar.

a.AbstractApplicationContext.prepareBeanFactory中加入ResourceEditorRegistrar.

 

B12、自定义命名空间和标签。XSD,namespacehandler,parser,META-INF/spring.handlers,META-INF/spring.schemas

0
1
分享到:
评论

相关推荐

    spring第五天 .pdf

    1. 重点掌握代理对象执行逻辑分析 2. 重点掌握Cglib代理技术之产生代理对象和代理对象执行逻辑分析 3. 认识Spring AOP中底层常用的一些核心类 4. 源码阅读之查找aop相关的BeanDefinitionParser流程 5. 源码阅读之...

    spring第四天.pdf

    11. 源码阅读之查找aop相关的BeanDefinitionParser流程课程目标 1. 了解什么是AOP? 2. 了解AOP能干什么? 3. 了解AOP都有哪些实现? 4. 掌握AOP核心概念(通知、切入点、切面、代理对象、目标对象、织入等) 5. ...

    计算机语言中spring全家桶去进行简单的功能实现

    在逐步去写spring源码的时候去体会spring中各个注解的作用使用的位置,也要去体会整体框架的核心逻辑。从spring到springmvc再到springboot的逐步简化代码的过程,核心功能都没有改变,如::IOC、AOP、Bean生命周期...

    【基于java-ssm】大学生兼职论坛管理系统实现源码+lw+部署文档+讲解

    在实现过程中,将提炼出 Spring 框架的核心逻辑,简化代码实现过程,保留重要功能,例如:IOC(控制反转)、AOP(面向切面编程)、Bean 生命周期管理、应用上下文、作用域、资源处理等内容。 适合人群:具备一定...

    SSH框架实现BBS完整版

    4.7 大致分析业务逻辑定义部分Dao实现 4.8 测试Dao实现 4.9 分析JSP中要实现的功能在实体中建立实体方法 4.10 建立Struts2映射路径 4.11 分析实体中需要的业务逻辑在Service中定义相应的方法 4.12 配置 配置Spring...

    SSH框架实现BBS完整版.2018_03_16

    4.7 大致分析业务逻辑定义部分Dao实现 4.8 测试Dao实现 4.9 分析JSP中要实现的功能在实体中建立实体方法 4.10 建立Struts2映射路径 4.11 分析实体中需要的业务逻辑在Service中定义相应的方法 4.12 配置 配置Spring...

    Java 基础核心总结 java全方面基础知识 java开发人员必备

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    Javascript aop(面向切面编程)之around(环绕)分析

    但是利用aop可以有效的改善js代码逻辑,比如前端框架dojo和yui3中AOP则被提升至自定义事件的一种内在机制,在源码中随处可见。得益于这种抽象使得dojo的自定义事件异常强大和灵活。dojo中aop的实现在dojo/aspect模块...

    SSM+课程设计+项目源代码+thymleaf

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    蓝色简约风毕业答辩PPT

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    Video基础知识简介

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    黑马程序员ssm代码分享

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程保留核心功能, 例如:I0C、AOP、Bean生命周期上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 能学到...

    软件工程课堂笔记+期末试题

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 能学...

    Apifox-windows-latest

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC, AOP、 Bean生命周期、上下文、作用域、资源处理等内容实现。适合人群:具备一定编程基础,工作1-3年的研发人能学到什么...

    该项目是gradle+springboot+freemarker的项目,是对学生基本信息的增删改查。

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    期末课设,基于·Android·开发

    在手写Spring 源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等内容实现。 适合人群:具备一定编程基础,工作1-3年的研发人员 ...

    maven3.6.3.zip

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC, AOP、 Bean生命周期、上下文、作用域、资源处理等内容实现。适合人群:具备一定编程基础,工作1-3年的研发人能学到什么...

    apache-tomcat-8.0.32

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC, AOP、 Bean生命周期、上下文、作用域、资源处理等内容实现。适合人群:具备一定编程基础,工作1-3年的研发人能学到什么...

    zookeeper-3.4.6.zip

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC, AOP、 Bean生命周期、上下文、作用域、资源处理等内容实现。适合人群:具备一定编程基础,工作1-3年的研发人能学到什么...

    apache-maven-3.2.5.zip

    在手写Spring源码的过程中会摘取整体框架中的核心逻辑,简化代码实现过程,保留核心功能,例如:IOC, AOP、 Bean生命周期、上下文、作用域、资源处理等内容实现。适合人群:具备一定编程基础,工作1-3年的研发人能学到什么...

Global site tag (gtag.js) - Google Analytics