`

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 AOP实现 项目源码 Myeclipse 直接导入可用

    **Spring AOP 实现详解** 在Java开发中,Spring...结合Myeclipse的强大功能,开发者能够更高效地实现和测试AOP逻辑。该项目源码为初学者提供了一个很好的实践平台,通过实际操作,你可以更好地掌握Spring AOP的精髓。

    五、Spring源码分析——Spring Aop

    《Spring AOP 源码分析》 在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦...

    Spring AOP介绍及源码分析

    **Spring AOP介绍** ...学习并掌握Spring AOP及其源码分析对于提升作为IT专业人员的技术水平至关重要,它不仅能够帮助我们编写更加优雅和简洁的代码,还能使我们更好地应对复杂的企业级应用需求。

    Spring Aop 引用新功能 源码

    通过源码分析,我们可以深入了解Spring AOP的工作原理,以及如何通过`IntroductionInterceptor`或`@AspectJ`来实现引入。理解并熟练运用这一特性,将有助于我们在实际开发中更好地进行代码解耦和模块化,提升软件的...

    Java spring AOP源码

    ### Java Spring AOP源码分析 #### 概述 在探讨Spring AOP源码之前,我们首先需要了解Spring AOP的基本概念以及它的工作原理。面向切面编程(Aspect-Oriented Programming, AOP)是一种编程范式,它通过将横切关注...

    spring-aop-ProxyFactoryBean 源码分析

    5. **源码分析**: 在`ProxyFactoryBean`的`getObject()`方法中,会调用`createAopProxy()`生成`AopProxy`,然后`AopProxy`的`getProxy()`方法返回实际的代理对象。`createAopProxy()`会根据配置判断使用JDK还是...

    spring-aop.pdf 源码电子书

    标题和描述中提到的是关于Spring AOP源码的电子书。Spring AOP(Aspect-Oriented Programming)是Spring框架的一个重要组成部分,它支持面向切面编程的实践,是为了解决面向对象编程中的横切关注点问题而设计的。在...

    死磕Spring之AOP篇 - Spring AOP两种代理对象的拦截处理(csdn)————程序.pdf

    在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态代理。 JDK 动态代理是基于接口的,它要求被代理的目标对象必须实现至少一个接口。Spring 使用 `java.lang.reflect.Proxy`...

    Spring AOP的底层实现技术

    总结来说,Spring AOP通过代理模式和切面编程思想,实现了代码的解耦和模块化,提高了软件的可维护性和可扩展性。了解并熟练掌握Spring AOP的底层实现技术,对于提升开发效率和编写高质量的Java应用程序具有重要意义...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    总结来说,Spring AOP通过动态代理实现了面向切面编程,利用反射在运行时生成代理对象并插入通知代码。这种设计让开发者能够专注于业务逻辑,而不必关心横切关注点的实现细节,提高了代码的可维护性和复用性。理解...

    spring aop实现日志功能

    标签"源码 工具"提示我们,了解这些知识点不仅需要掌握Spring AOP的使用,还可能涉及对Spring框架源码的阅读,以及熟悉各种开发工具,如IDE的AOP插件,用于辅助理解和调试AOP逻辑。同时,熟悉Maven或Gradle构建工具...

    spring aop 学习笔记

    - **代理(Proxy)**:Spring AOP创建的对象,用于实现切面的逻辑。 - **织入(Weaving)**:将切面应用到目标对象,创建代理的过程。可以发生在运行时或编译时。 2. **工作原理** - **动态代理**:Spring AOP...

    springAOP核心组件分析.pdf

    Spring AOP(面向切面编程)是Spring框架的一个重要组成部分,它允许开发者将横切关注点与业务逻辑分离,实现业务逻辑的模块化。AOP核心组件包括几个关键概念,如切面(Aspect)、通知(Advice)、连接点(Joinpoint...

    spring aop

    Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它提供了一种在程序运行时动态插入代码的能力,以实现跨切面的关注点,如日志、事务管理、权限控制等。通过AOP,开发者可以将...

    spring aop实例annotation方法实现

    在IT行业中,Spring AOP(面向切面编程)是一种强大的工具,它允许程序员在不修改原有业务代码的情况下,对程序进行功能增强。...在实际项目中,可以结合源码分析,深入理解其工作原理,以更好地利用这一强大的特性。

    spring aop实现日志分析管理

    在Spring AOP(面向切面编程)中实现日志分析管理是一种常见的做法,它能帮助开发者跟踪和理解系统运行过程中的行为,同时提供详细的错误日志以支持运维工作。通过元注解的方式,我们可以轻松地将日志记录功能集成到...

    Spring-AOP练习源码

    这个压缩包文件包含了关于Spring AOP的实践源码,通过分析这些源码,我们可以深入理解Spring AOP的工作原理和实际应用。 在Spring AOP中,"切面"(Aspect)是核心概念,它封装了横切关注点,如日志、事务管理等。切...

    spring源码分析(1-10)

    7. **Spring AOP中的拦截器调用实现**:Spring AOP使用Advisor和Interceptor实现拦截器链,处理方法调用前后的逻辑。MethodBeforeAdvice、AfterReturningAdvice等接口定义了拦截器的行为。 8. **Spring 驱动...

    spring aop 附带测试实例

    在提供的压缩包文件"springAOP"中,可能包含了以下内容: - **切面类(Aspect Class)**:包含切点和通知的Java类,可能使用了`@Aspect`注解。 - **目标类(Target Class)**:被AOP代理的对象,通常包含业务逻辑。...

    springaop

    标题 "springaop" 暗示我们关注的是Spring框架中的AOP(面向切面编程)模块。在Spring框架中,AOP是一种强大的工具,它允许程序员定义“切面”,这些切面可以封装横切关注点,如日志、事务管理、性能监控等,将它们...

Global site tag (gtag.js) - Google Analytics