Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the core classes of Spring AOP

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "what are the core classes of Spring AOP". The content of the explanation is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn what are the core classes of Spring AOP.

Class structure diagram

Let's first look at the structure diagram of the AnnotationAwareAspectJAutoProxyCreator class.

An introduction to some classes / interfaces in the figure above:

AspectJAwareAdvisorAutoProxyCreator: exposes the calling context of AspectJ and clarifies the priority rules of multiple Advisor from the same aspect in AspectJ.

AbstractAdvisorAutoProxyCreator: a generic automatic agent creator that builds AOP agents for a specific bean based on each consultant detected.

AbstractAutoProxyCreator: extends ProxyProcessorSupport and implements the SmartInstantiationAwareBeanPostProcessor and BeanFactoryAware interfaces, which is a BeanPostProcessor implementation that wraps each qualified bean with an AOP proxy and delegates to the specified interceptor before invoking the bean itself.

BeanFactoryAware: the Bean that implements this interface can know which BeanFactory,Bean it belongs to can find its collaborator through the Spring container (dependency lookup), but most Bean gets its collaborator through constructor parameters and Bean methods (dependency injection).

BeanPostProcessor: factory hook that allows custom modification of new bean instances. For example, check the tagged interface or use a proxy to wrap the bean. If we need to instantiate Bean in the Spring container, configure and add some logic before and after initialization, we can define the implementation of one or more BeanPostProcessor interfaces and register with the container.

InstantiationAwareBeanPostProcessor: a subinterface of BeanPostProcessor that adds callbacks before instantiation and callbacks after instantiation but before setting explicit properties or auto-assembly. It provides three methods internally, plus two methods within the BeanPostProcessor interface, and five methods are needed to implement this interface. The main function of the InstantiationAwareBeanPostProcessor interface lies in the things that need to be handled during the instantiation of the target object, including the process before and after the instantiation of the object and the property setting of the instance.

SmartInstantiationAwareBeanPostProcessor: the extension of the InstantiationAwareBeanPostProcessor interface has three more methods, a callback to predict the final type of processed bean, and five methods for the parent interface, so eight methods need to be implemented to implement this interface, and the main role is to deal with things that need to be handled during the instantiation of the target object.

In summary: AspectJAwareAdvisorAutoProxyCreator creates automatic proxies for AspectJ aspect classes.

Core class analysis

The two methods in the BeanPostProcessor interface, postProcessBeforeInitialization and postProcessAfterInitialization, are used to add some logic to Bean before and after initialization.

@ Nullable

Default Object postProcessBeforeInitialization (Object bean, String beanName) throws BeansException {

Return bean

}

@ Nullable

Default Object postProcessAfterInitialization (Object bean, String beanName) throws BeansException {

Return bean

}

InstantiationAwareBeanPostProcessor is a subinterface of BeanPostProcessor, which adds three new methods: postProcessBeforeInstantiation (the method called before the target object is instantiated, which can return a proxy of the target instance instead of the target instance), and postProcessAfterInstantiation (this method is executed after Bean instantiation and returns false, ignoring the setting of attribute values If true is returned, the property values will be set according to the normal process) and postProcessPropertyValues (property values will be modified and deleted in future versions)

@ Nullable

Default Object postProcessBeforeInstantiation (Class beanClass, String beanName) throws BeansException {

Return null

}

Default boolean postProcessAfterInstantiation (Object bean, String beanName) throws BeansException {

Return true

}

@ Nullable

Default PropertyValues postProcessPropertyValues (

PropertyValues pvs, PropertyDescriptor [] pds, Object bean, String beanName) throws BeansException {

Return pvs

}

The SmartInstantiationAwareBeanPostProcessor interface inherits the InstantiationAwareBeanPostProcessor interface, which defines three methods: predictBeanType (predicting the type of Bean), determineCandidateConstructors (choosing the appropriate constructor), and getEarlyBeanReference (solving circular reference problems).

@ Nullable

Default Class predictBeanType (Class beanClass, String beanName) throws BeansException {

Return null

}

@ Nullable

Default Constructor [] determineCandidateConstructors (Class beanClass, String beanName) throws BeansException {

Return null

}

Default Object getEarlyBeanReference (Object bean, String beanName) throws BeansException {

Return bean

}

AbstractAutoProxyCreator is a core class of AOP, which implements the SmartInstantiationAwareBeanPostProcessor and BeanFactoryAware interfaces, implements the logic of proxy creation, wraps each qualified bean with an AOP proxy, and delegates to the specified interceptor before invoking the bean itself.

The AbstractAdvisorAutoProxyCreator generic automatic proxy creator, which builds AOP proxies for special bean based on the enhancers that detect each AOP. Subclasses can override this findCandidateAdvisors () method to return a custom list of advisor for any object, and subclasses can override inherited AbstractAutoProxyCreator.shouldSkip () methods to exclude some objects from automatic proxies.

Protected List findCandidateAdvisors () {

Assert.state (this.advisorRetrievalHelper! = null, "No BeanFactoryAdvisorRetrievalHelper available")

Return this.advisorRetrievalHelper.findAdvisorBeans ()

}

AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator, exposing the invocation context of AspectJ and figuring out the recommended priority order of AspectJ when multiple enhancers come from the same aspect. Sort the rest by AspectJ priority:

@ Override

@ SuppressWarnings ("unchecked")

Protected List sortAdvisors (List advisors) {

List partiallyComparableAdvisors = new ArrayList (advisors.size ())

For (Advisor element: advisors) {

PartiallyComparableAdvisors.add (

New PartiallyComparableAdvisorHolder (element, DEFAULT_PRECEDENCE_COMPARATOR))

}

List sorted = PartialOrder.sort (partiallyComparableAdvisors)

If (sorted! = null) {

List result = new ArrayList (advisors.size ())

For (PartiallyComparableAdvisorHolder pcAdvisor: sorted) {

Result.add (pcAdvisor.getAdvisor ())

}

Return result

}

Else {

Return super.sortAdvisors (advisors)

}

}

These additional advisor are required when adding an ExposeInvocationInterceptor to the head of the enhancement chain, using AspectJ expression pointcuts, and using AspectJ-style advisor.

Protected void extendAdvisors (List candidateAdvisors) {

AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary (candidateAdvisors)

}

If the processor should not then consider using the given bean for automatic proxies, the subclass should override this method to return true

@ Override

Protected boolean shouldSkip (Class beanClass, String beanName) {

/ / TODO: Consider optimization by caching the list of the aspect names

List candidateAdvisors = findCandidateAdvisors ()

For (Advisor advisor: candidateAdvisors) {

If (advisor instanceof AspectJPointcutAdvisor & &

((AspectJPointcutAdvisor) advisor) .getAspectName () .equals (beanName)) {

Return true

}

}

Return super.shouldSkip (beanClass, beanName)

}

AspectJAwareAdvisorAutoProxyCreator also has a subclass called AnnotationAwareAspectJAutoProxyCreator, and the subclass AnnotationAwareAspectJAutoProxyCreator is used to handle all AspectJ annotation aspects in the current application context as well as Spring Advisor. If Spring AOP's agent-based model can apply any AspectJ annotated classes, their advisor will be automatically recognized, which covers method execution join points, and Spring Advisor processing follows the rules established in AbstractAdvisorAutoProxyCreator.

Generate proxy object

From using aop:xxx tags to automatically generate proxies, first look at AopNamespaceHandler, use aop:config tags to use ConfigBeanDefinitionParser parsing, use aop:aspectj-autoproxy tags to use AspectJAutoProxyBeanDefinitionParser parsing, and so on.

@ Override

Public void init () {

/ / In 2.0 XSD as well as in 2.1 XSD.

RegisterBeanDefinitionParser ("config", new ConfigBeanDefinitionParser ())

RegisterBeanDefinitionParser ("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser ())

RegisterBeanDefinitionDecorator ("scoped-proxy", new ScopedProxyBeanDefinitionDecorator ())

/ / Only in 2.0 XSD: moved to context namespace as of 2.1

RegisterBeanDefinitionParser ("spring-configured", new SpringConfiguredBeanDefinitionParser ())

}

Aop:config method uses AspectJAwareAdvisorAutoProxyCreator to create agents aop:aspectj-autoproxy uses AnnotationAwareAspectJAutoProxyCreator to create agents

ConfigBeanDefinitionParser.java

@ Override

@ Nullable

Public BeanDefinition parse (Element element, ParserContext parserContext) {

CompositeComponentDefinition compositeDef =

New CompositeComponentDefinition (element.getTagName (), parserContext.extractSource (element))

ParserContext.pushContainingComponent (compositeDef)

ConfigureAutoProxyCreator (parserContext, element); / / register AspectJAwareAdvisorAutoProxyCreator

List childElts = DomUtils.getChildElements (element)

For (Element elt: childElts) {

String localName = parserContext.getDelegate () .getLocalName (elt)

If (POINTCUT.equals (localName)) {

ParsePointcut (elt, parserContext)

}

Else if (ADVISOR.equals (localName)) {

ParseAdvisor (elt, parserContext)

}

Else if (ASPECT.equals (localName)) {

ParseAspect (elt, parserContext)

}

}

ParserContext.popAndRegisterContainingComponent ()

Return null

}

Private void configureAutoProxyCreator (ParserContext parserContext, Element element) {

AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary (parserContext, element)

}

AopConfigUtils.java

@ Override

@ Nullable

Public BeanDefinition parse (Element element, ParserContext parserContext) {

CompositeComponentDefinition compositeDef =

New CompositeComponentDefinition (element.getTagName (), parserContext.extractSource (element))

ParserContext.pushContainingComponent (compositeDef)

ConfigureAutoProxyCreator (parserContext, element); / / register AspectJAwareAdvisorAutoProxyCreator

List childElts = DomUtils.getChildElements (element)

For (Element elt: childElts) {

String localName = parserContext.getDelegate () .getLocalName (elt)

If (POINTCUT.equals (localName)) {

ParsePointcut (elt, parserContext)

}

Else if (ADVISOR.equals (localName)) {

ParseAdvisor (elt, parserContext)

}

Else if (ASPECT.equals (localName)) {

ParseAspect (elt, parserContext)

}

}

ParserContext.popAndRegisterContainingComponent ()

Return null

}

Private void configureAutoProxyCreator (ParserContext parserContext, Element element) {

AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary (parserContext, element)

}

AopConfigUtils.java

Public static void registerAspectJAutoProxyCreatorIfNecessary (

ParserContext parserContext, Element sourceElement) {

/ / the person registered here is AspectJAwareAdvisorAutoProxyCreator

BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary (

ParserContext.getRegistry (), parserContext.extractSource (sourceElement))

UseClassProxyingIfNecessary (parserContext.getRegistry (), sourceElement)

RegisterComponentIfNecessary (beanDefinition, parserContext); / / Registration component

}

@ Nullable

Public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary (

BeanDefinitionRegistry registry, @ Nullable Object source) {

Return registerOrEscalateApcAsRequired (AspectJAwareAdvisorAutoProxyCreator.class, registry, source)

}

AspectJAwareAdvisorAutoProxyCreator implements the interfaces described above such as BeanPostProcessor, which mainly acts on all Bean before and after Bean initialization and instantiation. InstantiationAwareBeanPostProcessor is a subinterface of BeanPostProcessor, but its call time occurs before Bean is instantiated, and postProcessBeforeInstantiation () is executed before actually calling doCreateBean () to create a bean instance.

AbstractAutoProxyCreator.java

@ Override

Public Object postProcessBeforeInstantiation (Class beanClass, String beanName) throws BeansException {

Object cacheKey = getCacheKey (beanClass, beanName); / / get a cached unique key (generate unique key based on beanClass and beanName)

/ / if the current targetSourcedBeans (TargetSource created through custom TargetSourceCreator) does not contain cacheKey

If (! StringUtils.hasLength (beanName) | |! this.targetSourcedBeans.contains (beanName)) {

If (this.advisedBeans.containsKey (cacheKey)) {/ / advisedBeans (the enhanced Bean, that is, the AOP proxy object) contains the current cacheKey and returns null, that is, following the default process of Spring

Return null

}

If (isInfrastructureClass (beanClass) | | shouldSkip (beanClass, beanName)) {/ / if it is an infrastructure class (such as the implementation of Advisor, Advice, AopInfrastructureBean), it will not be processed.

This.advisedBeans.put (cacheKey, Boolean.FALSE)

Return null

}

}

/ / if there is a custom TargetSource, create a proxy here

/ / disable unnecessary default instantiation of the target Bean:

/ / TargetSource will process the target instance in a custom manner.

TargetSource targetSource = getCustomTargetSource (beanClass, beanName)

If (targetSource! = null) {

If (StringUtils.hasLength (beanName)) {

This.targetSourcedBeans.add (beanName)

}

Object [] specificInterceptors = getAdvicesAndAdvisorsForBean (beanClass, beanName, targetSource)

Object proxy = createProxy (beanClass, beanName, specificInterceptors, targetSource)

This.proxyTypes.put (cacheKey, proxy.getClass ())

Return proxy

}

Return null

}

Create an AOP proxy through postProcessAfterInitialization () in AbstractAutoProxyCreator.

@ Override

Public Object postProcessAfterInitialization (@ Nullable Object bean, String beanName) throws BeansException {

If (bean! = null) {

Object cacheKey = getCacheKey (bean.getClass (), beanName)

If (! this.earlyProxyReferences.contains (cacheKey)) {/ / if you have previously called getEarlyBeanReference to get the wrapper target object to the AOP proxy object (if necessary), it will no longer be executed

Return wrapIfNecessary (bean, beanName, cacheKey); / / wraps the target object to the AOP proxy object (if required)

}

}

Return bean

}

Protected Object wrapIfNecessary (Object bean, String beanName, Object cacheKey) {

If (StringUtils.hasLength (beanName) & & this.targetSourcedBeans.contains (beanName)) {/ / Custom TargetSource via TargetSourceCreator does not need to be wrapped

Return bean

}

If (Boolean.FALSE.equals (this.advisedBeans.get (cacheKey) {/ / objects that should not be enhanced do not need to be wrapped

Return bean

}

If (isInfrastructureClass (bean.getClass ()) | | shouldSkip (bean.getClass (), beanName)) {/ / Infrastructure should not be guaranteed by skip

This.advisedBeans.put (cacheKey, Boolean.FALSE)

Return bean

}

/ / create a proxy if there is an advise.

Object [] specificInterceptors = getAdvicesAndAdvisorsForBean (bean.getClass (), beanName, null)

If (specificInterceptors! = DO_NOT_PROXY) {

This.advisedBeans.put (cacheKey, Boolean.TRUE)

Object proxy = createProxy (

Bean.getClass (), beanName, specificInterceptors, new SingletonTargetSource (bean); / / create a proxy object

This.proxyTypes.put (cacheKey, proxy.getClass ())

Return proxy

}

This.advisedBeans.put (cacheKey, Boolean.FALSE)

Return bean

} Thank you for your reading, the above is the content of "what are the core classes of Spring AOP". After the study of this article, I believe you have a deeper understanding of what the core classes of Spring AOP have, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report