Test case 1
Tangent point
@Component public class UserServiceImpl implements UserService { @Override public void save(UserInfo userInfo) { System.out.println("Execute save:"+userInfo.getName()); } }
Test case 2
section
@Aspect @Component public class TestAspect { @Pointcut("execution(* com.helloworld.service.impl.UserServiceImpl.*(..))") public void pointCut(){}; @Before(value = "pointCut()") public void methodBefore(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("Execution target method["+methodName+"]of<Before advice >,Input parameter"+ Arrays.asList(joinPoint.getArgs())); } @After(value = "pointCut()") public void methodAfter(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); System.out.println("Execution target method["+methodName+"]of<Post notification>,Input parameter"+Arrays.asList(joinPoint.getArgs())); } }
Test case 3
Test case: start the boot class and create a new spring container object AnnotationConfigApplicationContext
@Configuration @ComponentScan @EnableAspectJAutoProxy(proxyTargetClass = true) public class DemoApplication { public static void main( String[] args ) { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class); UserService userService = (UserService) ctx.getBean("userServiceImpl"); UserInfo userInfo = (UserInfo) ctx.getBean("user_zhangsan"); userService.save(userInfo); } }
First, navigate to creating the first bean instance DemoApplication
Code block 1: main
constructor
Parameter: args = []
package com.helloworld; public class DemoApplication { public static void main( String[] args ) { //args=[]; "*******"AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class); "(1) constructor " "Parameters: annotatedClasses=class com.helloworld.DemoApplication," UserService userService = (UserService) ctx.getBean("userServiceImpl"); UserInfo userInfo = (UserInfo) ctx.getBean("user_zhangsan"); userService.save(userInfo); } }
Code block 2: AnnotationConfigApplicationContext()
Refresh
Parameter: annotatedclasses = class com helloworld. DemoApplication,
package org.springframework.context.annotation; public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry{ public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //annotatedClasses=class com.helloworld.DemoApplication,; this(); register(annotatedClasses); //Register the configuration class in BeanDefinitionMap annotatedClasses=class com.helloworld.DemoApplication,; "*******"refresh(); "(2) Refresh" } }
Code block 3: refresh
Complete Bean factory initialization
package org.springframework.context.support; public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext{ @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //`startupShutdownMonitor ` the synchronization monitor is used for "Refresh" and "destroy". // Prepare this context for refreshing. ...... onRefresh(); // Check for listener beans and register them. registerListeners(); //10. Find the Listener bean in all registered beans and register it in the broadcaster // Instantiate all remaining (non-lazy-init) singletons. "***************"finishBeanFactoryInitialization(beanFactory); //11. Initialize the remaining (non lazy init) singletons beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; "(3) complete Bean Factory initialization" "Parameters: beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy" // Last step: publish corresponding event. finishRefresh(); //12. Finally: complete the refresh process, notify the lifecycle processor of the refresh process, and send a ContextRefreshEvent to notify others } catch (BeansException ex) { if (logger.isWarnEnabled()) { //If the value of mock starts with force, it will be degraded forcibly logger.warn("Exception encountered during context initialization - " + ...... resetCommonCaches(); //Reset common introspection caches in Spring's core, since wemight not ever need metadata for singleton beans anymore... Starting with us, resetting the common introspective cache in the spring core may no longer require the metadata of the singleton bean } } } }
Code block 4: finishBeanFactoryInitialization
Pre instantiation singleton
Parameter: beanfactory = org springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springfra…
package org.springframework.context.support; public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext{ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy; // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { ...... beanFactory.setTempClassLoader(null); //Stop using temporary class loader for type matching // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); //4. Freeze all Bean definitions. The registered Bean definitions will not be modified or further post processed, because the Bean instance object will be created soon beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; // Instantiate all remaining (non-lazy-init) singletons. "*******"beanFactory.preInstantiateSingletons(); //5. Instantiate all remaining (non lazy loading) singleton objects beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; "(4) Pre instantiation singleton" } }
Code block 5: preInstantiateSingletons
Get Bean
package org.springframework.beans.factory.support; public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory{ @Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Pre-instantiating singletons in " + this); ...... if (isEagerInit) { getBean(beanName); //6. If the bean corresponding to beanName is not a FactoryBean but just an ordinary bean, obtain the bean instance through beanName } } } else { "*******************"getBean(beanName); //6. If the bean corresponding to beanname is not a FactoryBean but just an ordinary bean, obtain the bean instance through beanname beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; "(5) obtain Bean" "Parameters: name=demoApplication" } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { //7. Traverse beanNames and trigger all post initialization callbacks of smartinitializingsingsingleton beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; Object singletonInstance = getSingleton(beanName); //7.1 get the bean instance corresponding to beanName singletonInstance=proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (singletonInstance instanceof SmartInitializingSingleton) { //7.2 judge whether the singletonInstance implements the smartinitializingsingsingleton interface ...... } } } } }
Code block 6: getBean
Get bean
Parameter: name=demoApplication
package org.springframework.beans.factory.support; public class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{ @Override public Object getBean(String name) throws BeansException { //name=demoApplication; "*******"return doGetBean(name, null, null, false); //Get the bean instance corresponding to name. If it does not exist, create one "(6) obtain bean" "Parameters: name=demoApplication" "Parameters: typeCheckOnly=false" } }
Code block 7: doGetBean
Get singleton
Parameter: name=demoApplication
Parameter: typeCheckOnly=false
package org.springframework.beans.factory.support; public class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, //name=demoApplication;typeCheckOnly=false; @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { ...... } } } // Create bean instance. if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; "*******************"sharedInstance = getSingleton(beanName, () -> { "(7) Get singleton" "Parameters: beanName=demoApplication" try { return createBean(beanName, mbd, args); //9.3. 4 create bean instance } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); //2. Delete the bean (if any) corresponding to the beanName from the singleton cache ...... } } return (T) bean; //11. Return the created bean instance object } }
Code block 8: getSingleton
Create Bean
Parameter: beanName=demoApplication
package org.springframework.beans.factory.support; public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry{ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { //beanName=demoApplication; Assert.notNull(beanName, "Bean name must not be null"); //Judge that beanname is not empty, and throw a runtime exception if it is empty beanName=demoApplication; synchronized (this.singletonObjects) { //1. Lock to avoid creating singleton objects repeatedly Object singletonObject = this.singletonObjects.get(beanName); //2. First check whether the bean instance corresponding to beanName exists in the cache. If it already exists, it will be returned directly ...... boolean newSingleton = false; //First, set the new newsingleton to false newSingleton=false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); //suppressedExceptions is used to record exception related information recordSuppressedExceptions=true; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); //Create exception list } try { "*******************"singletonObject = singletonFactory.getObject(); //6. Execute the getObject method of singletonFactory to obtain the bean instance "(8) establish Bean" "Parameters: beanName=demoApplication" "Parameters: mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null" newSingleton = true; //Mark as new singleton newSingleton=true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); //Whether the singleton objects appear implicitly at the same time - > if so, continue because the exception indicates the state. if (singletonObject == null) { //Check whether this singleton exists throw ex; ...... } return singletonObject; //Returns an instance in the cache } } }
Code block 9: createBean
Create bean
Parameter: beanName=demoApplication
Parameter: mbd=Root bean: class [com.helloworld.DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a]; scope=singleton; abstract=false;...
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; throws BeanCreationException { ...... catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { "***********"Object beanInstance = doCreateBean(beanName, mbdToUse, args); //5. Create a Bean instance (the method to actually create a Bean) "(9) establish bean" "Parameters: beanName=demoApplication" "Parameters: mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null" if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; //6. Return the created Bean instance } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. ...... throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } } }
Code block 10: doCreateBean
Create bean instance
Parameter: beanName=demoApplication
Parameter: mbd=Root bean: class [com.helloworld.DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a]; scope=singleton; abstract=false;...
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //1. Create a new Bean wrapper class if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); //2. If it is a FactoryBean, you need to remove the cache of the unfinished FactoryBean instance first } if (instanceWrapper == null) { "***********"instanceWrapper = createBeanInstance(beanName, mbd, args); //3. Create Bean instances with corresponding policies according to beanName, mbd and args, and return the wrapper class BeanWrapper instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a@6ee4d9ab ]; "(10) establish bean example" } final Object bean = instanceWrapper.getWrappedInstance(); //Wrapped instance object Class<?> beanType = instanceWrapper.getWrappedClass(); //The type of instance object wrapped beanType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; //(the field visible to the package, which is used to cache the determined class defined by a given bean), cache mbd.resolvedTargetType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; } // Allow post-processors to modify the merged bean definition. ...... } return exposedObject; //4. Return the object to be exposed as a bean reference. If there is no SmartInstantiationAwareBeanPostProcessor modification, the returned bean object is the bean object itself } }
Summary:
First, navigate to creating the first bean instance DemoApplication
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
Before creating DemoApplication, first call the pre method of the post processor registered in the previous article
Code block 11: createBean
Parsing before instantiation
Parameter: beanName=demoApplication
Parameter: mbd=Root bean: class [com.helloworld.DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a]; scope=singleton; abstract=false;...
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; throws BeanCreationException { ...... throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. "***********"Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //3. The processing before instantiation gives the instantiaawarebeanpostprocessor an opportunity to return the proxy object to replace the real bean instance to achieve the "short circuit" effect "(11) Parsing before instantiation" "Parameters: beanName=demoApplication" "Parameters: mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null" if (bean != null) { //4. If the bean is not empty, the default instantiation process of Spring will be skipped and the returned bean will be used directly return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } ...... "***********"Object beanInstance = doCreateBean(beanName, mbdToUse, args); //5. Create a Bean instance (the method to actually create a Bean) "(9)" throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } } }
Code block 12: resolvebeforeinstance
Apply Bean postprocessor before instantiation
Parameter: beanName=demoApplication
Parameter: mbd=Root bean: class [com.helloworld.DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a]; scope=singleton; abstract=false;...
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Nullable protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { //1.mbd is not synthetic, and InstantiationAwareBeanPostProcessor exists in BeanFactory mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; Class<?> targetType = determineTargetType(beanName, mbd); //2. Resolve the type of Bean instance corresponding to beanName targetType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; if (targetType != null) { "*******************"bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); //3. Post processor application before instantiation (instantiaawarebeanpostprocessor) "(12) Apply before instantiation Bean Post processor" "Parameters: beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a" "Parameters: beanName=demoApplication" if (bean != null) { //4. If the bean is not empty, the default instantiation process of Spring will be skipped and the returned bean will be used directly bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); //Therefore, the postProcessAfterInitialization method of the BeanPostProcessor implementation class can only be called here } } } mbd.beforeInstantiationResolved = (bean != null); //5. If the bean is not empty, assign beforeinstantiationresolved to true, which means it has been resolved before instantiation mbd.beforeInstantiationResolved=false; } return bean; } }
Code block 13: applybeanpostprocessors beforeinstance
Post processing before instantiation
Parameter: beanclass = class com helloworld. DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a
Parameter: beanName=demoApplication
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Nullable protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { //beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a;beanName=demoApplication; for (BeanPostProcessor bp : getBeanPostProcessors()) { //7.1 application postprocessor instantiaawarebeanpostprocessor bp=proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (bp instanceof InstantiationAwareBeanPostProcessor) { //2. Apply the instantiaawarebeanpostprocessor post processor to allow the postprocessbeforeinstance method to return the proxy of the bean object InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //Apply the post processor instantiawarebeanpostprocessor and call its postProcessPropertyValues method to process the properties that need dependency check. The annotated properties such as Autowired are injected here ibp=proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; "***************"Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //This method can return a constructed Bean instance, so it will not continue to execute the "normal process" of creating Bean instances, so as to achieve the effect of "short circuit". "(13) Post processing before instantiation" "Parameters: beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a" "Parameters: beanName=demoApplication" if (result != null) { return result; } } } return null; } }
Code block 14: postprocessbeforeinstance
Should skip
Parameter: beanclass = class com helloworld. DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a
Parameter: beanName=demoApplication
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a;beanName=demoApplication; Object cacheKey = getCacheKey(beanClass, beanName); //Get the cached key. If it is a FactoryBean, prefix it with & prefix. cacheKey=demoApplication; if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // beanName=demoApplication; if (this.advisedBeans.containsKey(cacheKey)) { return null; } "***********"if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { "(14) Should skip" "Parameters: beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a" "Parameters: beanName=demoApplication" this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection 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. ...... } return null; } }
Code block 15: shouldSkip
Find candidate notifications
Parameter: beanclass = class com helloworld. DemoApplication E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB23a7051a
Parameter: beanName=demoApplication
package org.springframework.aop.aspectj.autoproxy; public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator{ @Override protected boolean shouldSkip(Class<?> beanClass, String beanName) { //beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a;beanName=demoApplication; // TODO: Consider optimization by caching the list of the aspect names "*******"List<Advisor> candidateAdvisors = findCandidateAdvisors(); //1 - get the list of all intensifiers first candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(15) Find candidate notifications" for (Advisor advisor : candidateAdvisors) { // advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); //Call the parent class, and false is directly returned here false; } }
Code block 16: findCandidateAdvisors
Build aspectJ notifications
package org.springframework.aop.aspectj.annotation; public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator{ @Override protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. List<Advisor> advisors = super.findCandidateAdvisors(); //Add all the Spring advisors found according to superclass rules. Get Advisor implementation class // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { "***********"advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); //*Use @ Aspect annotation to parse * buildAspectJAdvisors here. This method finds out all enhancement methods and stores them in BeanFactory**** Take the calculate d logAspect as an example. Here are all the facet methods to find it [before, after, Around, etc.] "(16) structure aspectJ notice" } return advisors; //Finally, return these notifications InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 17: buildAspectJAdvisors
constructor
package org.springframework.aop.aspectj.annotation; public class BeanFactoryAspectJAdvisorsBuilder { public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; //aspectBeanNames mainly caches the facet definition classes that have been found if (aspectNames == null) { ...... continue; } if (this.advisorFactory.isAspect(beanType)) { // beanType=class com.helloworld.aop.TestAspect; aspectNames.add(beanName); //Add the bean to the aspectNames cache beanName=testAspect; AspectMetadata amd = new AspectMetadata(beanType, beanName); //Get the meta information of the current class through reflection if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { "*******************************"MetadataAwareAspectInstanceFactory factory = // factory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; "(17) constructor " "Parameters: beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy" "Parameters: name=testAspect" new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //Generate spring aop advisor, which parses Advice and Pointcut annotations classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; if (this.beanFactory.isSingleton(beanName)) { // beanName=testAspect; this.advisorsCache.put(beanName, classAdvisors); //Cache the resolved Bean name and the enhancement on the class, and each Bean is resolved only once classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; beanName=testAspect; } else { this.aspectFactoryCache.put(beanName, factory); //Add cache } ...... } } return advisors; //Finally, return these notifications } }
Code block 18: BeanFactoryAspectInstanceFactory()
constructor
Parameter: beanfactory = org springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springfra…
Parameter: name=testAspect
package org.springframework.aop.aspectj.annotation; public class BeanFactoryAspectInstanceFactory implements MetadataAwareAspectInstanceFactory{ public BeanFactoryAspectInstanceFactory(BeanFactory beanFactory, String name, @Nullable Class<?> type) { //beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy;name=testAspect; Assert.notNull(beanFactory, "BeanFactory must not be null"); // beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy; Assert.notNull(name, "Bean name must not be null"); // name=testAspect; this.beanFactory = beanFactory; //Assigned to beanfactory in Context this. beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.Context.annotation.internalConfigurationAnnotationProcessor,org.springframework.Context.annotation.internalAutowiredAnnotationProcessor,org.springframework.Context.annotation.internalCommonAnnotationProcessor,org.springframework.Context.event.internalEventListenerProcessor,org.springframework.Context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; this.name = name; //Implement the BeanNameAware interface to get the name of the Bean this.name=testAspect; Class<?> resolvedType = type; if (type == null) { //If the class instance is null (not written in the configuration file) resolvedType = beanFactory.getType(name); // resolvedType=class com.helloworld.aop.TestAspect; Assert.notNull(resolvedType, "Unresolvable bean type - explicitly specify the aspect class"); // resolvedType=class com.helloworld.aop.TestAspect; } "*******"this.aspectMetadata = new AspectMetadata(resolvedType, name); "(18) constructor " "Parameters: aspectClass=class com.helloworld.aop.TestAspect" "Parameters: aspectName=testAspect" } }
Code block 19: AspectMetadata()
Create facet object metadata object
Parameter: aspectclass = class com helloworld. aop. TestAspect
Parameter: aspectName=testAspect
package org.springframework.aop.aspectj.annotation; public class AspectMetadata implements Serializable{ public AspectMetadata(Class<?> aspectClass, String aspectName) { //aspectClass=class com.helloworld.aop.TestAspect;aspectName=testAspect; this.aspectName = aspectName; //Name of section this.aspectName=testAspect; Class<?> currClass = aspectClass; // currClass=class com.helloworld.aop.TestAspect; ...... } this.aspectClass = ajType.getJavaClass(); // this.aspectClass=class com.helloworld.aop.TestAspect; this.ajType = ajType; switch (this.ajType.getPerClause().getKind()) { case SINGLETON: "***************"this.perClausePointcut = Pointcut.TRUE; // this.perClausePointcut=Pointcut.TRUE; "(19) Create facet object metadata object" return; case PERTARGET: case PERTHIS: AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); ajexp.setLocation(aspectClass.getName()); ajexp.setExpression(findPerClause(aspectClass)); ajexp.setPointcutDeclarationScope(aspectClass); this.perClausePointcut = ajexp; ...... throw new AopConfigException( "PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass); } } }
Summary:
Before creating DemoApplication, first call the pre method of the post processor registered in the previous article
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation()
- AbstractAutoProxyCreator.postProcessBeforeInstantiation()
- AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
- AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
- BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
- BeanFactoryAspectInstanceFactory.BeanFactoryAspectInstanceFactory()
- AspectMetadata.AspectMetadata()
Instantiation aspect pre notification
Code block 20: buildAspectJAdvisors
Find aop notifications
package org.springframework.aop.aspectj.annotation; public class BeanFactoryAspectJAdvisorsBuilder { public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; //aspectBeanNames mainly caches the facet definition classes that have been found if (aspectNames == null) { ...... if (this.advisorFactory.isAspect(beanType)) { // beanType=class com.helloworld.aop.TestAspect; aspectNames.add(beanName); //Add the bean to the aspectNames cache beanName=testAspect; AspectMetadata amd = new AspectMetadata(beanType, beanName); //Get the meta information of the current class through reflection if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { "*******************************"MetadataAwareAspectInstanceFactory factory = // factory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; "(17)" new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); "*******************************"List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //Generate spring aop advisor, which parses Advice and Pointcut annotations classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(20) lookup aop notice" "Parameters: aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'" if (this.beanFactory.isSingleton(beanName)) { // beanName=testAspect; this.advisorsCache.put(beanName, classAdvisors); //Cache the resolved Bean name and the enhancement on the class, and each Bean is resolved only once classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; beanName=testAspect; } else { this.aspectFactoryCache.put(beanName, factory); //Add cache } advisors.addAll(classAdvisors); // classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } ...... } } return advisors; //Finally, return these notifications } }
Code block 21: getAdvisors
Get notification
Parameter: aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //Get the class object of Aspect() annotation from aspectMetadata aspectClass=class com.helloworld.aop.TestAspect; String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //Gets the class name of the Aspect() annotation aspectName=testAspect; ...... // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = // lazySingletonAspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); //Record in cache for (Method method : getAdvisorMethods(aspectClass)) { // method=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint); method=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint); method=protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException; method=public boolean java.lang.Object.equals(java.lang.Object); method=protected void java.lang.Object.finalize() throws java.lang.Throwable; method=public final native java.lang.Class java.lang.Object.getClass(); method=public native int java.lang.Object.hashCode(); method=public final native void java.lang.Object.notify(); method=public final native void java.lang.Object.notifyAll(); method=private static native void java.lang.Object.registerNatives(); method=public java.lang.String java.lang.Object.toString(); method=public final void java.lang.Object.wait() throws java.lang.InterruptedException; method=public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException; method=public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException; "***********"Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); //Construct InstantiationModelAwarePointcutAdvisorImpl advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; "(21) Get notification" "Parameters: candidateAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)" "Parameters: aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'" "Parameters: declarationOrderInAspect=0" "Parameters: aspectName=testAspect" if (advisor != null) { advisors.add(advisor); //5. Add Advisor object to container advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); //If the looking enhancer is not empty and the enhanced delay initialization is configured, the synchronous instantiation enhancer needs to be added in the first place ...... } return advisors; //Finally, return these notifications InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 22: getAdvisor
constructor
Parameter: candidateadvicemethod = public void com helloworld. aop. TestAspect. methodBefore(org.aspectj.lang.JoinPoint)
Parameters: aspectinstancefactory = lazysingletonaspectinstancefactory decorator: decorating beanfactory aspectinstancefactory: bean nam
Parameter: declarationOrderInAspect=0
Parameter: aspectName=testAspect
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, //candidateAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint);aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrderInAspect=0;aspectName=testAspect; int declarationOrderInAspect, String aspectName) { ...... AspectJExpressionPointcut expressionPointcut = getPointcut( // expressionPointcut=AspectJExpressionPointcut: () pointCut(); candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } "*******"return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, "(22) constructor " "Parameters: declaredPointcut=AspectJExpressionPointcut: () pointCut()" "Parameters: aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)" "Parameters: aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4" "Parameters: aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'" "Parameters: declarationOrder=0" "Parameters: aspectName=testAspect" this, aspectInstanceFactory, declarationOrderInAspect, aspectName); // InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } }
Code block 23: InstantiationModelAwarePointcutAdvisorImpl()
Create pointcut and notification object instances
Parameters: declaredPointcut=AspectJExpressionPointcut: () pointCut()
Parameter: aspectjadvicemethod = public void com helloworld. aop. TestAspect. methodBefore(org.aspectj.lang.JoinPoint)
Parameter: aspectjadvisorfactory = org springframework. aop. aspectj. annotation. ReflectiveAspectJAdvisorFactory@420a85c4
Parameters: aspectinstancefactory = lazysingletonaspectinstancefactory decorator: decorating beanfactory aspectinstancefactory: bean nam
Parameter: declarationOrder=0
Parameter: aspectName=testAspect
package org.springframework.aop.aspectj.annotation; public class InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor{ public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, //declaredPointcut=AspectJExpressionPointcut: () pointCut();aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint);aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4;aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrder=0;aspectName=testAspect; Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; //Tangent expression this.declaredPointcut=AspectJExpressionPointcut: () pointCut(); this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //Section class this.declaringClass=class com.helloworld.aop.TestAspect; this.methodName = aspectJAdviceMethod.getName(); //The name of the notification method this.methodName=methodBefore; this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //Notification method parameters this.parameterTypes=interface org.aspectj.lang.JoinPoint,; "*******"this.aspectJAdviceMethod = aspectJAdviceMethod; //Notification method this.aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint); "(23) Create pointcut and notification object instances" this.aspectJAdvisorFactory = aspectJAdvisorFactory; //Advisor factory of aspectJ this.aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4 ; this.aspectInstanceFactory = aspectInstanceFactory; //Factory class of slice instance this.aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; this.declarationOrder = declarationOrder; //Order of sections this.declarationOrder=0; this.aspectName = aspectName; //Name of section this.aspectName=testAspect; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( ...... this.lazy = false; // this.lazy=false; this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); //This method focuses on creating an advice object this.instantiatedAdvice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; } } }
Summary:
Instantiation aspect pre notification
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation()
- AbstractAutoProxyCreator.postProcessBeforeInstantiation()
- AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
- AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
- BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
- ReflectiveAspectJAdvisorFactory.getAdvisors()
- ReflectiveAspectJAdvisorFactory.getAdvisor()
- InstantiationModelAwarePointcutAdvisorImpl.InstantiationModelAwarePointcutAdvisorImpl()
Instantiate slice post notification
Code block 24: buildAspectJAdvisors
Find notifications
package org.springframework.aop.aspectj.annotation; public class BeanFactoryAspectJAdvisorsBuilder { public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; //aspectBeanNames mainly caches the facet definition classes that have been found if (aspectNames == null) { ...... if (this.advisorFactory.isAspect(beanType)) { // beanType=class com.helloworld.aop.TestAspect; aspectNames.add(beanName); //Add the bean to the aspectNames cache beanName=testAspect; AspectMetadata amd = new AspectMetadata(beanType, beanName); //Get the meta information of the current class through reflection if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { "*******************************"MetadataAwareAspectInstanceFactory factory = // factory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; "(17)" new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); "*******************************"List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //Generate spring aop advisor, which parses Advice and Pointcut annotations classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(24) Find notifications" "Parameters: aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'" if (this.beanFactory.isSingleton(beanName)) { // beanName=testAspect; this.advisorsCache.put(beanName, classAdvisors); //Cache the resolved Bean name and the enhancement on the class, and each Bean is resolved only once classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; beanName=testAspect; } else { this.aspectFactoryCache.put(beanName, factory); //Add cache } advisors.addAll(classAdvisors); // classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } ...... } } return advisors; //Finally, return these notifications } }
Code block 25: getAdvisors
Get notification
Parameter: aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //Get the class object of Aspect() annotation from aspectMetadata aspectClass=class com.helloworld.aop.TestAspect; String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //Gets the class name of the Aspect() annotation aspectName=testAspect; ...... // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = // lazySingletonAspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); //Record in cache for (Method method : getAdvisorMethods(aspectClass)) { // method=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint); method=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint); method=protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException; method=public boolean java.lang.Object.equals(java.lang.Object); method=protected void java.lang.Object.finalize() throws java.lang.Throwable; method=public final native java.lang.Class java.lang.Object.getClass(); method=public native int java.lang.Object.hashCode(); method=public final native void java.lang.Object.notify(); method=public final native void java.lang.Object.notifyAll(); method=private static native void java.lang.Object.registerNatives(); method=public java.lang.String java.lang.Object.toString(); method=public final void java.lang.Object.wait() throws java.lang.InterruptedException; method=public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException; method=public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException; "***********"Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); //Construct InstantiationModelAwarePointcutAdvisorImpl advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; "(25) Get notification" "Parameters: candidateAdviceMethod=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)" "Parameters: aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'" "Parameters: declarationOrderInAspect=1" "Parameters: aspectName=testAspect" if (advisor != null) { advisors.add(advisor); //5. Add Advisor object to container advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); //If the looking enhancer is not empty and the enhanced delay initialization is configured, the synchronous instantiation enhancer needs to be added in the first place ...... } return advisors; //Finally, return these notifications InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 26: getAdvisor
constructor
Parameter: candidateadvicemethod = public void com helloworld. aop. TestAspect. methodAfter(org.aspectj.lang.JoinPoint)
Parameters: aspectinstancefactory = lazysingletonaspectinstancefactory decorator: decorating beanfactory aspectinstancefactory: bean nam
Parameter: declarationOrderInAspect=1
Parameter: aspectName=testAspect
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, //candidateAdviceMethod=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint);aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrderInAspect=1;aspectName=testAspect; int declarationOrderInAspect, String aspectName) { ...... AspectJExpressionPointcut expressionPointcut = getPointcut( // expressionPointcut=AspectJExpressionPointcut: () pointCut(); candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } "*******"return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, "(26) constructor " "Parameters: declaredPointcut=AspectJExpressionPointcut: () pointCut()" "Parameters: aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)" "Parameters: aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4" "Parameters: aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'" "Parameters: declarationOrder=1" "Parameters: aspectName=testAspect" this, aspectInstanceFactory, declarationOrderInAspect, aspectName); // InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } }
Code block 27: InstantiationModelAwarePointcutAdvisorImpl()
Create pointcut and notification object instances
Parameters: declaredPointcut=AspectJExpressionPointcut: () pointCut()
Parameter: aspectjadvicemethod = public void com helloworld. aop. TestAspect. methodAfter(org.aspectj.lang.JoinPoint)
Parameter: aspectjadvisorfactory = org springframework. aop. aspectj. annotation. ReflectiveAspectJAdvisorFactory@420a85c4
Parameters: aspectinstancefactory = lazysingletonaspectinstancefactory decorator: decorating beanfactory aspectinstancefactory: bean nam
Parameter: declarationOrder=1
Parameter: aspectName=testAspect
package org.springframework.aop.aspectj.annotation; public class InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor{ public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, //declaredPointcut=AspectJExpressionPointcut: () pointCut();aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint);aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4;aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrder=1;aspectName=testAspect; Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; //Tangent expression this.declaredPointcut=AspectJExpressionPointcut: () pointCut(); this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //Section class this.declaringClass=class com.helloworld.aop.TestAspect; this.methodName = aspectJAdviceMethod.getName(); //The name of the notification method this.methodName=methodAfter; this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //Notification method parameters this.parameterTypes=interface org.aspectj.lang.JoinPoint,; "*******"this.aspectJAdviceMethod = aspectJAdviceMethod; //Notification method this.aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint); "(27) Create pointcut and notification object instances" this.aspectJAdvisorFactory = aspectJAdvisorFactory; //Advisor factory of aspectJ this.aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4 ; this.aspectInstanceFactory = aspectInstanceFactory; //Factory class of slice instance this.aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; this.declarationOrder = declarationOrder; //Order of sections this.declarationOrder=1; this.aspectName = aspectName; //Name of section this.aspectName=testAspect; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( ...... this.lazy = false; // this.lazy=false; this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); //This method focuses on creating an advice object this.instantiatedAdvice=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; } } }
Summary:
Instantiate slice post notification
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation()
- AbstractAutoProxyCreator.postProcessBeforeInstantiation()
- AspectJAwareAdvisorAutoProxyCreator.shouldSkip()
- AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
- BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
- ReflectiveAspectJAdvisorFactory.getAdvisors()
- ReflectiveAspectJAdvisorFactory.getAdvisor()
- InstantiationModelAwarePointcutAdvisorImpl.InstantiationModelAwarePointcutAdvisorImpl()
Navigate to create bean instance userServiceImpl
Code block 28: getBean
Get bean
Parameter: name=userServiceImpl
package org.springframework.beans.factory.support; public class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{ @Override public Object getBean(String name) throws BeansException { //name=userServiceImpl; "*******"return doGetBean(name, null, null, false); //Get the bean instance corresponding to name. If it does not exist, create one "(28) obtain bean" "Parameters: name=userServiceImpl" "Parameters: typeCheckOnly=false" } }
Code block 29: doGetBean
Get singleton
Parameter: name=userServiceImpl
Parameter: typeCheckOnly=false
package org.springframework.beans.factory.support; public class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, //name=userServiceImpl;typeCheckOnly=false; @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { ...... } } } // Create bean instance. if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; "*******************"sharedInstance = getSingleton(beanName, () -> { "(29) Get singleton" "Parameters: beanName=userServiceImpl" try { return createBean(beanName, mbd, args); //9.3. 4 create bean instance } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); //2. Delete the bean (if any) corresponding to the beanName from the singleton cache ...... } } return (T) bean; //11. Return the created bean instance object } }
Code block 30: getSingleton
Create Bean
Parameter: beanName=userServiceImpl
package org.springframework.beans.factory.support; public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry{ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { //beanName=userServiceImpl; Assert.notNull(beanName, "Bean name must not be null"); //Judge that beanname is not empty, and throw a runtime exception if it is empty beanName=userServiceImpl; synchronized (this.singletonObjects) { //1. Lock to avoid creating singleton objects repeatedly Object singletonObject = this.singletonObjects.get(beanName); //2. First check whether the bean instance corresponding to beanName exists in the cache. If it already exists, it will be returned directly ...... boolean newSingleton = false; //First, set the new newsingleton to false newSingleton=false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); //suppressedExceptions is used to record exception related information recordSuppressedExceptions=false; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); //Create exception list } try { "*******************"singletonObject = singletonFactory.getObject(); //6. Execute the getObject method of singletonFactory to obtain the bean instance "(30) establish Bean" "Parameters: beanName=userServiceImpl" "Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]" newSingleton = true; //Mark as new singleton newSingleton=true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); //Whether the singleton objects appear implicitly at the same time - > if so, continue because the exception indicates the state. if (singletonObject == null) { //Check whether this singleton exists throw ex; ...... } return singletonObject; //Returns an instance in the cache } } }
Code block 31: createBean
Create bean
Parameter: beanName=userServiceImpl
Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; aut…
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; throws BeanCreationException { ...... catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { "***********"Object beanInstance = doCreateBean(beanName, mbdToUse, args); //5. Create a Bean instance (the method to actually create a Bean) "(31) establish bean" "Parameters: beanName=userServiceImpl" "Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]" if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; //6. Return the created Bean instance } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. ...... throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } } }
Code block 32: doCreateBean
Create Bean instance
Parameter: beanName=userServiceImpl
Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; aut…
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //1. Create a new Bean wrapper class if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); //2. If it is a FactoryBean, you need to remove the cache of the unfinished FactoryBean instance first } if (instanceWrapper == null) { "***********"instanceWrapper = createBeanInstance(beanName, mbd, args); //3. Create Bean instances with corresponding policies according to beanName, mbd and args, and return the wrapper class BeanWrapper instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; "(32) establish Bean example" "Parameters: beanName=userServiceImpl" "Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]" } final Object bean = instanceWrapper.getWrappedInstance(); //Wrapped instance object Class<?> beanType = instanceWrapper.getWrappedClass(); //The type of instance object wrapped beanType=class com.helloworld.service.impl.UserServiceImpl; if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; //(the field visible to the package, which is used to cache the determined class defined by a given bean), cache mbd.resolvedTargetType=class com.helloworld.service.impl.UserServiceImpl; } // Allow post-processors to modify the merged bean definition. ...... } return exposedObject; //4. Return the object to be exposed as a bean reference. If there is no SmartInstantiationAwareBeanPostProcessor modification, the returned bean object is the bean object itself } }
Code block 33: createBeanInstance
Instantiate bean
Parameter: beanName=userServiceImpl
Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; aut…
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); //Parsing bean type information beanClass=class com.helloworld.service.impl.UserServiceImpl; ...... ctors = mbd.getPreferredConstructors(); //Get the preferred constructor, possibly the default constructor if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); //Constructor auto injection } // No special handling: simply use no-arg constructor. "*******"return instantiateBean(beanName, mbd); //6. If there is no special processing, the default constructor is used for bean instantiation org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; "(33) instantiation bean" } }
Summary:
Navigate to create bean instance userServiceImpl
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.populateBean()
- AutowiredAnnotationBeanPostProcessor.postProcessProperties()
- InjectionMetadata.inject()
- AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject()
- DefaultListableBeanFactory.resolveDependency()
- DefaultListableBeanFactory.doResolveDependency()
- DependencyDescriptor.resolveCandidate()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.createBeanInstance()
Call the postprocessor method of AbstractAutoProxyCreator
Code block 34: doCreateBean
Initialize Bean
Parameter: beanName=userServiceImpl
Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; aut…
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; throws BeanCreationException { // Instantiate the bean. ...... "***********"instanceWrapper = createBeanInstance(beanName, mbd, args); //3. Create Bean instances with corresponding policies according to beanName, mbd and args, and return the wrapper class BeanWrapper instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; "(32)" } // Initialize the bean instance. Object exposedObject = bean; //Initialize the bean instance. Initialize the bean instance. try { populateBean(beanName, mbd, instanceWrapper); //9. Fill in the bean attributes; If there may be properties that depend on other beans, the dependent bean instance will be recursively initialized mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; beanName=userServiceImpl; instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; "***********"exposedObject = initializeBean(beanName, exposedObject, mbd); //10. Initialize the bean "(34) initialization Bean" "Parameters: beanName=userServiceImpl" "Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]" } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); ...... } return exposedObject; //4. Return the object to be exposed as a bean reference. If there is no SmartInstantiationAwareBeanPostProcessor modification, the returned bean object is the bean object itself } }
Code block 35: initializeBean
Apply Bean post processor after initialization
Parameter: beanName=userServiceImpl
Parameters: mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; aut…
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; if (System.getSecurityManager() != null) { //4. Call initialization method AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); //Special bean processing: Aware, BeanClassLoaderAware, beanfactory Aware ...... catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //Loop through the postProcessBeforeInitialization method of the post processor of those beans mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; "***********"wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); //4. After initialization, the postProcessAfterInitialization method of BeanPostProcessor is applied to allow the bean instance to be wrapped "(35) Apply after initialization Bean Post processor" "Parameters: beanName=userServiceImpl" } return wrappedBean; //5. Return wrappedBean } }
Code block 36: applyBeanPostProcessorsAfterInitialization
After the object is initialized, the post processor is called.
Parameter: beanName=userServiceImpl
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) //beanName=userServiceImpl; throws BeansException { Object result = existingBean; //existingBean is the original object for (BeanPostProcessor processor : getBeanPostProcessors()) { // processor=proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; "***********"Object current = processor.postProcessAfterInitialization(result, beanName); //Execute the BeanPostProcessor in the spring container "(36) After the object is initialized, the post processor is called." "Parameters: beanName=userServiceImpl" if (current == null) { return result; } result = current; //Implementation of multi-layer agent } return result; } }
Code block 37: postProcessAfterInitialization
Need enhancement
Parameter: beanName=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { //beanName=userServiceImpl; if (bean != null) { //4. If the bean is not empty, the default instantiation process of Spring will be skipped and the returned bean will be used directly Object cacheKey = getCacheKey(bean.getClass(), beanName); //Attempt to get cache cacheKey=userServiceImpl; if (this.earlyProxyReferences.remove(cacheKey) != bean) { // cacheKey=userServiceImpl; "***************"return wrapIfNecessary(bean, beanName, cacheKey); //Proxy object "(37) Need enhancement" } } return bean; } }
Summary:
Call the postprocessor method of AbstractAutoProxyCreator
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.populateBean()
- AutowiredAnnotationBeanPostProcessor.postProcessProperties()
- InjectionMetadata.inject()
- AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject()
- DefaultListableBeanFactory.resolveDependency()
- DefaultListableBeanFactory.doResolveDependency()
- DependencyDescriptor.resolveCandidate()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.initializeBean()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization()
- AbstractAutoProxyCreator.postProcessAfterInitialization()
Match the notification according to the pointcut expression to find the matching notification
Code block 38: postProcessAfterInitialization
Need enhancement
Parameter: beanName=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { //beanName=userServiceImpl; if (bean != null) { //4. If the bean is not empty, the default instantiation process of Spring will be skipped and the returned bean will be used directly Object cacheKey = getCacheKey(bean.getClass(), beanName); //Attempt to get cache cacheKey=userServiceImpl; if (this.earlyProxyReferences.remove(cacheKey) != bean) { // cacheKey=userServiceImpl; "***************"return wrapIfNecessary(bean, beanName, cacheKey); //Proxy object "(38) Need enhancement" "Parameters: beanName=userServiceImpl" "Parameters: cacheKey=userServiceImpl" } } return bean; } }
Code block 39: wrapIfNecessary
Get notification for bean
Parameter: beanName=userServiceImpl
Parameter: cacheKey=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //beanName=userServiceImpl;cacheKey=userServiceImpl; if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } ...... if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } // Create proxy if we have advice. "*******"Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //Create proxy if we have advice. Enhanced method acquisition specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(39) obtain bean Notice of" "Parameters: beanClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: beanName=userServiceImpl" if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //Inserts a value into the proxy collection cacheKey=userServiceImpl; Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); //Agent type cacheKey=userServiceImpl; return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } }
Code block 40: getAdvicesAndAdvisorsForBean
Find qualified consultants
Parameter: beanclass = class com helloworld. service. impl. UserServiceImpl
Parameter: beanName=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator{ @Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( //beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl; Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { "*******"List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //Return the corresponding notification through the findEligibleAdvisors method, which returns all notifications that can be applied to the specified Bean advisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(40) Find qualified consultants" "Parameters: beanClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: beanName=userServiceImpl" if (advisors.isEmpty()) { return DO_NOT_PROXY; //DO_NOT_PROXY is null } return advisors.toArray(); //If the advisors is not empty, it is converted to an array and returned org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 41: findEligibleAdvisors
Find consultants you can apply for
Parameter: beanclass = class com helloworld. service. impl. UserServiceImpl
Parameter: beanName=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator{ protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl; List<Advisor> candidateAdvisors = findCandidateAdvisors(); //1 - get the list of all intensifiers first candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "*******"List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //2 - get the list of enhancers applied to the current target class eligibleAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(41) Find consultants you can apply for" "Parameters: candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON," "Parameters: beanClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: beanName=userServiceImpl" extendAdvisors(eligibleAdvisors); //This method is a hook method for subclass override extensions eligibleAdvisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; if (!eligibleAdvisors.isEmpty()) { // eligibleAdvisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; eligibleAdvisors = sortAdvisors(eligibleAdvisors); //Sort eligibleAdvisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } return eligibleAdvisors; // org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 42: findadvisors thatcanapply
Find available notifications
Parameters: candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.hellow…
Parameter: beanclass = class com helloworld. service. impl. UserServiceImpl
Parameter: beanName=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator{ protected List<Advisor> findAdvisorsThatCanApply( //candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl; List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); //Set the beanname of the target Bean of the proxy to ThreadLocal beanName=userServiceImpl; try { "***********"return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); //1 - find the enhancer that can act on the target Bean among the candidate enhancers InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(42) Find available notifications" "Parameters: candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON," "Parameters: clazz=class com.helloworld.service.impl.UserServiceImpl" } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } }
Code block 43: findadvisors that can apply
Judge whether it is available
Parameters: candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.hellow…
Parameter: clazz = class com helloworld. service. impl. UserServiceImpl
package org.springframework.aop.support; public class AopUtils { public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { //candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;clazz=class com.helloworld.service.impl.UserServiceImpl; if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } ...... boolean hasIntroductions = !eligibleAdvisors.isEmpty(); //Currently not used, so the value is false hasIntroductions=false; for (Advisor candidate : candidateAdvisors) { // candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (candidate instanceof IntroductionAdvisor) { // already processed continue; } "***********"if (canApply(candidate, clazz, hasIntroductions)) { // clazz=class com.helloworld.service.impl.UserServiceImpl; hasIntroductions=false; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; clazz=class com.helloworld.service.impl.UserServiceImpl; hasIntroductions=false; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; "(43) Judge whether it is available" "Parameters: advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON" "Parameters: targetClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: hasIntroductions=false" eligibleAdvisors.add(candidate); //2 - add notification enhancements candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } } return eligibleAdvisors; // InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Code block 44: canApply
Judge whether it is available
Parameters: advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.T…
Parameter: targetclass = class com helloworld. service. impl. UserServiceImpl
Parameter: hasIntroductions=false
package org.springframework.aop.support; public class AopUtils { public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { //advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON;targetClass=class com.helloworld.service.impl.UserServiceImpl;hasIntroductions=false; if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); //Introductions enhance class level matching } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; //According to the above analysis, the final candidate aspect is BeanFactoryTransactionAttributeSourceAdvisor, which implements PointcutAdvisor pca=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; "***********"return canApply(pca.getPointcut(), targetClass, hasIntroductions); //Execute true; "(44) Judge whether it is available" "Parameters: pc=AspectJExpressionPointcut: () pointCut()" "Parameters: targetClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: hasIntroductions=false" } else { // It doesn't have a pointcut so we assume it applies. return true; } } }
Code block 45: canApply
Match using tangent expression
Parameter: pc=AspectJExpressionPointcut: () pointCut()
Parameter: targetclass = class com helloworld. service. impl. UserServiceImpl
Parameter: hasIntroductions=false
package org.springframework.aop.support; public class AopUtils { public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { //pc=AspectJExpressionPointcut: () pointCut();targetClass=class com.helloworld.service.impl.UserServiceImpl;hasIntroductions=false; Assert.notNull(pc, "Pointcut must not be null"); // pc=AspectJExpressionPointcut: () pointCut(); if (!pc.getClassFilter().matches(targetClass)) { return false; ...... for (Class<?> clazz : classes) { // clazz=class com.helloworld.service.impl.UserServiceImpl; Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); //Get all Method objects of the current class through reflection methods=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo),protected void java.lang.Object.finalize() throws java.lang.Throwable,public final void java.lang.Object.wait() throws java.lang.InterruptedException,public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException,public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException,public boolean java.lang.Object.equals(java.lang.Object),public java.lang.String java.lang.Object.toString(),public native int java.lang.Object.hashCode(),public final native java.lang.Class java.lang.Object.getClass(),protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException,public final native void java.lang.Object.notify(),public final native void java.lang.Object.notifyAll(),private static native void java.lang.Object.registerNatives(),; for (Method method : methods) { //Get all methods of the interface method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : "***********************"methodMatcher.matches(method, targetClass)) { // targetClass=class com.helloworld.service.impl.UserServiceImpl; method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); hasIntroductions=false; "(45) Match using tangent expression" return true; } } } return false; } }
Summary:
Match the notification according to the pointcut expression to find the matching notification
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.populateBean()
- AutowiredAnnotationBeanPostProcessor.postProcessProperties()
- InjectionMetadata.inject()
- AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject()
- DefaultListableBeanFactory.resolveDependency()
- DefaultListableBeanFactory.doResolveDependency()
- DependencyDescriptor.resolveCandidate()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.initializeBean()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization()
- AbstractAutoProxyCreator.postProcessAfterInitialization()
- AbstractAutoProxyCreator.wrapIfNecessary()
- AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean()
- AbstractAdvisorAutoProxyCreator.findEligibleAdvisors()
- AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply()
- AopUtils.findAdvisorsThatCanApply()
- AopUtils.canApply()
- AopUtils.canApply()
Create aop proxy object
Code block 46: wrapIfNecessary
Create proxy
Parameter: beanName=userServiceImpl
Parameter: cacheKey=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //beanName=userServiceImpl;cacheKey=userServiceImpl; if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } ...... } // Create proxy if we have advice. "*******"Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //Create proxy if we have advice. Enhanced method acquisition specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(39)" if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //Inserts a value into the proxy collection cacheKey=userServiceImpl; "***********"Object proxy = createProxy( "(46) Create proxy" "Parameters: beanClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: beanName=userServiceImpl" "Parameters: specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON," "Parameters: targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]" bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); //Agent type cacheKey=userServiceImpl; return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } }
Code block 47: createProxy
Get agent
Parameter: beanclass = class com helloworld. service. impl. UserServiceImpl
Parameter: beanName=userServiceImpl
Parameter: specificinterceptors = org springframework. aop. interceptor. ExposeInvocationInterceptor. ADVISOR,InstantiationModelAwarePoin…
Parameters: Targetsource = singletontargetsource for target object [com. HelloWorld. Service. Impl UserServiceImpl@23aa363a ]
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, //beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl;specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]; @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { ...... proxyFactory.setFrozen(this.freezeProxy); //It is used to control whether the modification notification is allowed after the agent factory is configured. The default value is false (indicating that modification is not allowed) if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); //It has been filtered } "*******"return proxyFactory.getProxy(getProxyClassLoader()); //Create proxy "(47) Get agent" } }
Code block 48: getProxy
Create AOP proxy
package org.springframework.aop.framework; public class ProxyFactory extends ProxyCreatorSupport{ public Object getProxy(@Nullable ClassLoader classLoader) { "*******"return createAopProxy().getProxy(classLoader); //Create an AOP proxy and get the proxy object "(48) establish AOP agent" } }
Code block 49: createAopProxy
Create AOP proxy
package org.springframework.aop.framework; public class ProxyCreatorSupport extends AdvisedSupport{ protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } "*******"return getAopProxyFactory().createAopProxy(this); //this here is actually ProxyFactory "(49) establish AOP agent" "Parameters: config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" } }
Code block 50: createAopProxy
init
Parameter: config = org springframework. aop. framework. ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor…
package org.springframework.aop.framework; public class DefaultAopProxyFactory implements AopProxyFactory{ @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { // config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; Class<?> targetClass = config.getTargetClass(); //Gets the class that needs to be proxied targetClass=class com.helloworld.service.impl.UserServiceImpl; ...... throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); //Create JDK dynamic AOP proxy object } "***********"return new ObjenesisCglibAopProxy(config); //Otherwise, use CGLIB proxy "(50) init" "Parameters: config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" } else { return new JdkDynamicAopProxy(config); //Create JDK dynamic AOP proxy object } } }
Code block 51: CglibAopProxy()
constructor
Parameter: config = org springframework. aop. framework. ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor…
package org.springframework.aop.framework; public class CglibAopProxy implements AopProxy{ public CglibAopProxy(AdvisedSupport config) throws AopConfigException { //config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; Assert.notNull(config, "AdvisedSupport must not be null"); //There is only one constructor with AdvisedSupport type. This type mentioned above is the related configuration for generating agent classes. It must not be empty, or an error of parameter exception will be thrown config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) { throw new AopConfigException("No advisors and no TargetSource specified"); //Notifiers and target sources need to be defined in the AdvisedSupport configuration class. } "*******"this.advised = config; //The config here is the previous proxyfactory this.advised=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; "(51) constructor " this.advisedDispatcher = new AdvisedDispatcher(this.advised); } }
Summary:
Create aop proxy object
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.populateBean()
- AutowiredAnnotationBeanPostProcessor.postProcessProperties()
- InjectionMetadata.inject()
- AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject()
- DefaultListableBeanFactory.resolveDependency()
- DefaultListableBeanFactory.doResolveDependency()
- DependencyDescriptor.resolveCandidate()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.initializeBean()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization()
- AbstractAutoProxyCreator.postProcessAfterInitialization()
- AbstractAutoProxyCreator.wrapIfNecessary()
- AbstractAutoProxyCreator.createProxy()
- ProxyFactory.getProxy()
- ProxyCreatorSupport.createAopProxy()
- DefaultAopProxyFactory.createAopProxy()
- CglibAopProxy.CglibAopProxy()
Create a proxy object for userServiceImpl
Code block 52: wrapIfNecessary
Create proxy
Parameter: beanName=userServiceImpl
Parameter: cacheKey=userServiceImpl
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //beanName=userServiceImpl;cacheKey=userServiceImpl; if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } ...... } // Create proxy if we have advice. "*******"Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //Create proxy if we have advice. Enhanced method acquisition specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; "(39)" if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //Inserts a value into the proxy collection cacheKey=userServiceImpl; "***********"Object proxy = createProxy( "(52) Create proxy" "Parameters: beanClass=class com.helloworld.service.impl.UserServiceImpl" "Parameters: beanName=userServiceImpl" "Parameters: specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON," "Parameters: targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]" bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); //Agent type cacheKey=userServiceImpl; return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } }
Code block 53: createProxy
Get agent
Parameter: beanclass = class com helloworld. service. impl. UserServiceImpl
Parameter: beanName=userServiceImpl
Parameter: specificinterceptors = org springframework. aop. interceptor. ExposeInvocationInterceptor. ADVISOR,InstantiationModelAwarePoin…
Parameters: Targetsource = singletontargetsource for target object [com. HelloWorld. Service. Impl UserServiceImpl@23aa363a ]
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, //beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl;specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]; @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { ...... proxyFactory.setFrozen(this.freezeProxy); //It is used to control whether the modification notification is allowed after the agent factory is configured. The default value is false (indicating that modification is not allowed) if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); //It has been filtered } "*******"return proxyFactory.getProxy(getProxyClassLoader()); //Create proxy "(53) Get agent" } }
Code block 54: getProxy
Get agent
package org.springframework.aop.framework; public class ProxyFactory extends ProxyCreatorSupport{ public Object getProxy(@Nullable ClassLoader classLoader) { "*******"return createAopProxy().getProxy(classLoader); //Create an AOP proxy and get the proxy object "(54) Get agent" } }
Code block 55: getProxy
Create proxy classes and instances, the classic cglib steps to create dynamic proxies
package org.springframework.aop.framework; public class CglibAopProxy implements AopProxy{ @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); ...... // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); //Set callback type types=class org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor,class org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor,class org.springframework.aop.framework.CglibAopProxy$SerializableNoOp,class org.springframework.aop.framework.CglibAopProxy$StaticDispatcher,class org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher,class org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor,class org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor,; // Generate the proxy class and create a proxy instance. "***********"return createProxyClassAndInstance(enhancer, callbacks); //Create and return a proxy class "(55) Building proxy class instances" "Parameters: callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e," } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } } }
Code block 56: createProxyClassAndInstance
New instance
Parameter: callbacks = org springframework. aop. framework. CglibAopProxy$ DynamicAdvisedInterceptor@101639ae ,org. springframework. aop. fra…
package org.springframework.aop.framework; public class ObjenesisCglibAopProxy extends CglibAopProxy{ @Override @SuppressWarnings("unchecked") protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) { //callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e,; Class<?> proxyClass = enhancer.createClass(); //① The proxy class is generated proxyClass=class com.helloworld.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$9344f1; Object proxyInstance = null; if (objenesis.isWorthTrying()) { try { "***************"proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache()); //If spring is not configured objenesis. Ignore, a proxy implementation is created "(56) New instance" "Parameters: clazz=class com.helloworld.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$479344f1" "Parameters: useCache=true" } catch (Throwable ex) { logger.debug("Unable to instantiate proxy using Objenesis, " + "falling back to regular proxy construction", ex); } } if (proxyInstance == null) { ...... ((Factory) proxyInstance).setCallbacks(callbacks); // callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e,; return proxyInstance; } }
Code block 57: newInstance
Returns a proxy object instance
Parameter: clazz = class com helloworld. service. impl. UserServiceImpl E n h a n c e r B y S p r i n g C G L I B EnhancerBySpringCGLIB EnhancerBySpringCGLIB479344f1
Parameter: useCache=true
package org.springframework.objenesis; public class SpringObjenesis implements Objenesis{ public <T> T newInstance(Class<T> clazz, boolean useCache) { //clazz=class com.helloworld.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$$479344f1;useCache=true; if (!useCache) { return newInstantiatorOf(clazz).newInstance(); } "*******"return getInstantiatorOf(clazz).newInstance(); "(57) Return the proxy object instance to complete the creation of dynamic proxy" } }
Summary:
Create a proxy object for userServiceImpl
- DemoApplication.main()
- AnnotationConfigApplicationContext.AnnotationConfigApplicationContext()
- AbstractApplicationContext.refresh()
- AbstractApplicationContext.finishBeanFactoryInitialization()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.populateBean()
- AutowiredAnnotationBeanPostProcessor.postProcessProperties()
- InjectionMetadata.inject()
- AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject()
- DefaultListableBeanFactory.resolveDependency()
- DefaultListableBeanFactory.doResolveDependency()
- DependencyDescriptor.resolveCandidate()
- AbstractBeanFactory.getBean()
- AbstractBeanFactory.doGetBean()
- DefaultSingletonBeanRegistry.getSingleton()
- AbstractAutowireCapableBeanFactory.createBean()
- AbstractAutowireCapableBeanFactory.doCreateBean()
- AbstractAutowireCapableBeanFactory.initializeBean()
- AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization()
- AbstractAutoProxyCreator.postProcessAfterInitialization()
- AbstractAutoProxyCreator.wrapIfNecessary()
- AbstractAutoProxyCreator.createProxy()
- ProxyFactory.getProxy()
- CglibAopProxy.getProxy()
- ObjenesisCglibAopProxy.createProxyClassAndInstance()
- SpringObjenesis.newInstance()
appendix
Source code full text, comments, and runtime variables with Ellipsis
Full code: refresh
package org.springframework.context.support; public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext{ @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //`startupShutdownMonitor ` the synchronization monitor is used for "Refresh" and "destroy". // Prepare this context for refreshing. prepareRefresh(); //Set environment and verify parameters. // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //Create BeanFactory (DefaultListableBeanFactor) and load bean definition information. BeanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication]; root of factory hierarchy; // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); //Set BeanFactory BeanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication]; root of factory hierarchy; try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); //4. The subclass coverage method does additional processing: it is currently empty. beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication]; root of factory hierarchy; // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); //5. Execute various PostProcessor processors of BeanFactory BeanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); //6. Register the bean processor created by the intercepting bean. This is just registration. The real call is at the time of getBean. beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; // Initialize message source for this context. initMessageSource(); //7. Initialize the context Message source, i.e. Message bodies in different languages (i18n) // Initialize event multicaster for this context. initApplicationEventMulticaster(); //8. Initialize application event broadcast // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); //10. Find the Listener bean in all registered beans and register it in the broadcaster // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); //11. Initialize the remaining (non lazy init) singletons beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; // Last step: publish corresponding event. finishRefresh(); //12. Finally: complete the refresh process, notify the lifecycle processor of the refresh process, and send a ContextRefreshEvent to notify others } catch (BeansException ex) { if (logger.isWarnEnabled()) { //If the value of mock starts with force, it will be degraded forcibly logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); //Flag indicating whether the applicationContext has been activated. Set it to false // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); //Reset common introspection caches in Spring's core, since wemight not ever need metadata for singleton beans anymore... Starting with us, resetting the common introspective cache in the spring core may no longer require the metadata of the singleton bean } } } }
Complete code: finishBeanFactoryInitialization
package org.springframework.context.support; public class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext{ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //beanFactory=org.springframework.beans.factory.support.DefaultListableBeanFactory@1dfe2924: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator]; root of factory hierarchy; // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { //2. If beanfactory has not registered an embedded value parser before, it will register the default embedded value parser: it is mainly used for parsing annotation attribute values. beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); //Add an embedded value parser to parse the value of annotation attributes } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); //3. Initialize loadtimeweaveaware bean instance object weaverAwareNames=[]; for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); //The getBean method is equivalent to instantiating a Bean object } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); //Stop using temporary class loader for type matching // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); //4. Freeze all Bean definitions. The registered Bean definitions will not be modified or further post processed, because the Bean instance object will be created soon beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); //5. Instantiate all remaining (non lazy loading) singleton objects beanFactory=org. springframework. beans. factory. support. DefaultListableBeanFactory@1dfe2924 : defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListene rFactory,demoApplication,testAspect,userController,userServiceImpl,user_ zhangsan,org. springframework. aop. config. internalAutoProxyCreator]; root of factory hierarchy; } }
Full code: preInstantiateSingletons
package org.springframework.beans.factory.support; public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory{ @Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //Iterate over a copy to allow for init methods which in turn register new bean definitions.While this may not be part of the regular factory bootstrap, it does otherwise work fine. Get the beanName list, this Beandefinitionnames saves all beannames beanNames=org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator,; // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { //7. Traverse beanNames and trigger all post initialization callbacks of smartinitializingsingsingleton beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //3. Get the MergedBeanDefinition corresponding to beanName bd=Root bean: class [org.springframework.context.annotation.ConfigurationClassPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.annotation.CommonAnnotationBeanPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.event.EventListenerMethodProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.event.DefaultEventListenerFactory]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [com.helloworld.aop.TestAspect]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\aop\TestAspect.class]; bd=Root bean: class [com.helloworld.controller.UserController]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\controller\UserController.class]; bd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; bd=Root bean: class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //4. Bean instance corresponding to BD: not abstract class & & singleton & & not lazy loading bd=Root bean: class [org.springframework.context.annotation.ConfigurationClassPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.annotation.CommonAnnotationBeanPostProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.event.EventListenerMethodProcessor]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [org.springframework.context.event.DefaultEventListenerFactory]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; bd=Root bean: class [com.helloworld.aop.TestAspect]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\aop\TestAspect.class]; bd=Root bean: class [com.helloworld.controller.UserController]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\controller\UserController.class]; bd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; bd=Root bean: class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; if (isFactoryBean(beanName)) { //5. Judge whether the bean corresponding to beanName is FactoryBean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //? If it is? factoryBean, then? Plus? &, Create factory first? bean? if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; //Strong rotation boolean isEagerInit; //5.2 judge whether the FactoryBean wants to be initialized urgently if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); //6. If the bean corresponding to beanName is not a FactoryBean but just an ordinary bean, obtain the bean instance through beanName } } } else { getBean(beanName); //6. If the bean corresponding to beanname is not a FactoryBean but just an ordinary bean, obtain the bean instance through beanname beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { //7. Traverse beanNames and trigger all post initialization callbacks of smartinitializingsingsingleton beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; Object singletonInstance = getSingleton(beanName); //7.1 get the bean instance corresponding to beanName singletonInstance=proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (singletonInstance instanceof SmartInitializingSingleton) { //7.2 judge whether the singletonInstance implements the smartinitializingsingsingleton interface final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; //Subclass of smartinitializingsingsingleton if (System.getSecurityManager() != null) { //4. Call initialization method AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); //? Callback? afterSingletonsInstantiated()? Method, can you do something in the callback? return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); //? Callback? afterSingletonsInstantiated()? Method, can you do something in the callback? } } } } }
Complete code: doGetBean
package org.springframework.beans.factory.support; public class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory{ @SuppressWarnings("unchecked") protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, //name=demoApplication;typeCheckOnly=false; @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); //1. Resolve beanname, mainly resolve the alias and remove the prefix "&" of FactoryBean beanName=demoApplication; Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); //2. Try to get the instance corresponding to beanName from the cache if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { //1. Loop PropertySources if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); //3.1 return the instance object corresponding to beanName (mainly used for special processing of factorybeans. Ordinary beans will directly return sharedInstance itself) } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { //Example: if there is an attribute of B in A and an attribute of A in B, when dependency injection occurs, it will cause circular dependency when A has not been created, because the creation of B returns to create A again throw new BeanCurrentlyInCreationException(beanName); //If there are other threads creating this bean at this time, skip } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //4. If it is not found, check the parentBeanFactory if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { //5.1 if the parentBeanFactory exists and beanName does not have a bean definition in the current BeanFactory, try to get the bean instance from the parentBeanFactory // Not found -> check parent. String nameToLookup = originalBeanName(name); //5.2 resolve alias to real beanName if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); //Delegate to constructor getBean() for processing } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); //Instantiate the object to the parent container } else { return (T) parentBeanFactory.getBean(nameToLookup); //Without args, it is delegated to the standard getBean() } } if (!typeCheckOnly) { //Flag bit. If it is not a type check, it means that you want to create a bean. Here, make a record in the collection markBeanAsCreated(beanName); //6. If you create a bean instance instead of just doing type detection, put the beanname in the alreadyCreated cache beanName=demoApplication; } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //7. Retrieve MergedBeanDefinition according to beanName (delete MergedBeanDefinition in step 6 and get a new one here) mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; checkMergedBeanDefinition(mbd, beanName, args); //7.1 check MergedBeanDefinition mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; beanName=demoApplication; // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); //8. Get the bean name collection that the current bean depends on. You need to instantiate the bean you depend on before instantiating yourself if (dependsOn != null) { for (String dep : dependsOn) { //8.1 traverse the bean name collection that the current bean depends on if (isDependent(beanName, dep)) { //8.2 check whether dep depends on beanName, that is, check whether there is circular dependency throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); //8.4 register the dependency between dep and beanName in the cache try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); //9.3. 4 create bean instance } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); //2. Delete the bean (if any) corresponding to the beanName from the singleton cache throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); //9.1. 2 return the instance object corresponding to beanName } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; //9.2 creation of bean s with scope as prototype try { beforePrototypeCreation(beanName); //9.3. 3. Operation before instance creation (save beanName to the prototypes currentyincreation cache) prototypeInstance = createBean(beanName, mbd, args); //9.2. 2 create Bean instance } finally { afterPrototypeCreation(beanName); //9.3. 5. Operation after instance creation (remove the created beanName from the prototypesCurrentlyInCreation cache) } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); //9.2. 4. Return the instance object corresponding to beanName } else { String scopeName = mbd.getScope(); //9.3. 1 get the scope instance from the cache according to the scopeName final Scope scope = this.scopes.get(scopeName); //Instantiate bean on specified scope if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); //The scope property cannot receive null values } try { Object scopedInstance = scope.get(beanName, () -> { beforePrototypeCreation(beanName); //9.3. 3. Operation before instance creation (save beanName to the prototypes currentyincreation cache) try { return createBean(beanName, mbd, args); //9.3. 4 create bean instance } finally { afterPrototypeCreation(beanName); //9.3. 5. Operation after instance creation (remove the created beanName from the prototypesCurrentlyInCreation cache) } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); //9.3. 6 return the instance object corresponding to beanName } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); //If an exception occurs during the creation of the bean instance, remove the beanName from the alreadyCreated cache throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); //10.1 if the type is wrong, try to convert the bean type if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); //If the conversion is unsuccessful, an exception is thrown } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); //If the conversion is unsuccessful, an exception is thrown } } return (T) bean; //11. Return the created bean instance object } }
Complete code: getSingleton
package org.springframework.beans.factory.support; public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry{ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { //beanName=demoApplication; Assert.notNull(beanName, "Bean name must not be null"); //Judge that beanname is not empty, and throw a runtime exception if it is empty beanName=demoApplication; synchronized (this.singletonObjects) { //1. Lock to avoid creating singleton objects repeatedly Object singletonObject = this.singletonObjects.get(beanName); //2. First check whether the bean instance corresponding to beanName exists in the cache. If it already exists, it will be returned directly if (singletonObject == null) { //Check whether this singleton exists if (this.singletonsCurrentlyInDestruction) { //3. If the bean instance corresponding to beanname does not exist in the cache, create the bean throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { //If non mandatory is set, if it cannot be found, it will be returned directly logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); //5. Operations before creating a singleton beanName=demoApplication; boolean newSingleton = false; //First, set the new newsingleton to false newSingleton=false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); //suppressedExceptions is used to record exception related information recordSuppressedExceptions=true; if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); //Create exception list } try { singletonObject = singletonFactory.getObject(); //6. Execute the getObject method of singletonFactory to obtain the bean instance newSingleton = true; //Mark as new singleton newSingleton=true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); //Whether the singleton objects appear implicitly at the same time - > if so, continue because the exception indicates the state. if (singletonObject == null) { //Check whether this singleton exists throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; //Recycle exception list } afterSingletonCreation(beanName); //7. Operations after creating a single instance beanName=demoApplication; } if (newSingleton) { addSingleton(beanName, singletonObject); //8. If it is a new singleton object, add the beanname and the corresponding bean instance to the cache (singletonObjects, registeredsinglets) beanName=demoApplication; } } return singletonObject; //Returns an instance in the cache } } }
Complete code: createBean
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; throws BeanCreationException { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //Bean definition information mbdToUse=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); //1. Resolve the Bean type corresponding to beanName, for example: com joonwhee. open. demo. service. impl. UserServiceImpl resolvedClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { //It is judged here that the BeanDefinition only specifies the ClassName and sets the resolved Class object for direct use during instantiation below mbdToUse = new RootBeanDefinition(mbd); //This copy replaces the mdb for subsequent operations mbdToUse.setBeanClass(resolvedClass); //The resolved resolvedClass is assigned to the copied object, and the copied copy is used for subsequent operations } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); //2. Methods for verifying and preparing overrides (marking and verifying the override attribute) mbdToUse=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); //3. The processing before instantiation gives the instantiaawarebeanpostprocessor an opportunity to return the proxy object to replace the real bean instance to achieve the "short circuit" effect if (bean != null) { //4. If the bean is not empty, the default instantiation process of Spring will be skipped and the returned bean will be used directly return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); //5. Create a Bean instance (the method to actually create a Bean) if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; //6. Return the created Bean instance } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } } }
Complete code: doCreateBean
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) //beanName=demoApplication;mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; //1. Create a new Bean wrapper class if (mbd.isSingleton()) { //9. Create beans for different scopes mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); //2. If it is a FactoryBean, you need to remove the cache of the unfinished FactoryBean instance first } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); //3. Create Bean instances with corresponding policies according to beanName, mbd and args, and return the wrapper class BeanWrapper instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a@6ee4d9ab ]; } final Object bean = instanceWrapper.getWrappedInstance(); //Wrapped instance object Class<?> beanType = instanceWrapper.getWrappedClass(); //The type of instance object wrapped beanType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; //(the field visible to the package, which is used to cache the determined class defined by a given bean), cache mbd.resolvedTargetType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); //Autowired annotation realizes the pre parsing of injection type through this method beanType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; beanName=demoApplication; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; //Note that this bd has been processed by the post processor of MergedBeanDefinitionPostProcessor, so applymergedbeandefinitionpostprocessor will not be called again when the Bean is created the second time mbd.postProcessed=true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && // earlySingletonExposure=true; isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { //If initializeBean(..) If the previously instantiated object is changed during the process, the previously exposed object is also injected by other objects, which will lead to the non guarantee of the uniqueness of the singleton object. Here is responsible for checking the existence of this situation. If this situation exists, You can force the singleton object of earlyExposed not to be used by setting alloweegerinit of getBeanNamesOfType to false. if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //Add the created bean instance to ectFactory in advance to avoid circular dependency later beanName=demoApplication; } // Initialize the bean instance. Object exposedObject = bean; //Initialize the bean instance. Initialize the bean instance. try { populateBean(beanName, mbd, instanceWrapper); //9. Fill in the bean attributes; If there may be properties that depend on other beans, the dependent bean instance will be recursively initialized mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; beanName=demoApplication; instanceWrapper=org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a@6ee4d9ab ]; exposedObject = initializeBean(beanName, exposedObject, mbd); //10. Initialize the bean } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { //If initializeBean(..) If the previously instantiated object is changed during the process, the previously exposed object is also injected by other objects, which will lead to the non guarantee of the uniqueness of the singleton object. Here is responsible for checking the existence of this situation. If this situation exists, You can force the singleton object of earlyExposed not to be used by setting alloweegerinit of getBeanNamesOfType to false. Object earlySingletonReference = getSingleton(beanName, false); //11. If the instance is allowed to be exposed in advance, the cycle dependency check is performed if (earlySingletonReference != null) { //11.1 the earlysingletonreference will not be empty only if the currently resolved bean has a circular dependency if (exposedObject == bean) { exposedObject = earlySingletonReference; //11.2 if the exposedObject is not enhanced in the initializeBean method, the previous circular reference will not be affected } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); //11.4 get the beanName array of all beans that depend on the current bean Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { //11.5 try to remove the instances of these beans, because the beans they depend on have been enhanced, and the beans they depend on are equivalent to dirty data actualDependentBeans.add(dependentBean); //11.6 remove failed and add to actualDependentBeans } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); //12. Register beans for destruction. There are three types of beans for destruction: Custom destroy method, DisposableBean interface, and DestructionAwareBeanPostProcessor mbd=Root bean: class [com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; beanName=demoApplication; } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; //4. Return the object to be exposed as a bean reference. If there is no SmartInstantiationAwareBeanPostProcessor modification, the returned bean object is the bean object itself } }
Full code: postprocessbeforeinstance
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { //beanClass=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$$23a7051a;beanName=demoApplication; Object cacheKey = getCacheKey(beanClass, beanName); //Get the cached key. If it is a FactoryBean, prefix it with & prefix. cacheKey=demoApplication; if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // beanName=demoApplication; if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection 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. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); //If TargetSource is configured, the bean is generated using the rules defined by TargetSource if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); //Get slice Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); //Create a proxy object this.proxyTypes.put(cacheKey, proxy.getClass()); //Agent type return proxy; } return null; } }
Complete code: buildAspectJAdvisors
package org.springframework.aop.aspectj.annotation; public class BeanFactoryAspectJAdvisorsBuilder { public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; //aspectBeanNames mainly caches the facet definition classes that have been found if (aspectNames == null) { synchronized (this) { //Double lock lazy loading aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new ArrayList<>(); //Record in cache aspectNames = new ArrayList<>(); String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( // beanNames=org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,demoApplication,testAspect,userController,userServiceImpl,user_zhangsan,org.springframework.aop.config.internalAutoProxyCreator,environment,systemProperties,systemEnvironment,org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry,messageSource,applicationEventMulticaster,; this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { //7. Traverse beanNames and trigger all post initialization callbacks of smartinitializingsingsingleton beanName=org.springframework.context.annotation.internalConfigurationAnnotationProcessor; beanName=org.springframework.context.annotation.internalAutowiredAnnotationProcessor; beanName=org.springframework.context.annotation.internalCommonAnnotationProcessor; beanName=org.springframework.context.event.internalEventListenerProcessor; beanName=org.springframework.context.event.internalEventListenerFactory; beanName=demoApplication; beanName=testAspect; beanName=userController; beanName=userServiceImpl; beanName=user_zhangsan; beanName=org.springframework.aop.config.internalAutoProxyCreator; beanName=environment; beanName=systemProperties; beanName=systemEnvironment; beanName=org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry; beanName=messageSource; beanName=applicationEventMulticaster; if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. Class<?> beanType = this.beanFactory.getType(beanName); //Get the class information of the bean beanType=class org.springframework.context.annotation.ConfigurationClassPostProcessor; beanType=class org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor; beanType=class org.springframework.context.annotation.CommonAnnotationBeanPostProcessor; beanType=class org.springframework.context.event.EventListenerMethodProcessor; beanType=class org.springframework.context.event.DefaultEventListenerFactory; beanType=class com.helloworld.DemoApplication$$EnhancerBySpringCGLIB$a7051a; beanType=class com.helloworld.aop.TestAspect; beanType=class com.helloworld.controller.UserController; beanType=class com.helloworld.service.impl.UserServiceImpl; beanType=class com.helloworld.entity.UserInfo; beanType=class org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator; beanType=class org.springframework.core.env.StandardEnvironment; beanType=class java.util.Properties; beanType=class java.util.Collections$UnmodifiableMap; beanType=class org.springframework.context.annotation.ConfigurationClassParser$ImportStack; beanType=class org.springframework.context.support.DelegatingMessageSource; beanType=class org.springframework.context.event.SimpleApplicationEventMulticaster; if (beanType == null) { continue; } if (this.advisorFactory.isAspect(beanType)) { // beanType=class com.helloworld.aop.TestAspect; aspectNames.add(beanName); //Add the bean to the aspectNames cache beanName=testAspect; AspectMetadata amd = new AspectMetadata(beanType, beanName); //Get the meta information of the current class through reflection if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = // factory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); //Generate spring aop advisor, which parses Advice and Pointcut annotations classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; if (this.beanFactory.isSingleton(beanName)) { // beanName=testAspect; this.advisorsCache.put(beanName, classAdvisors); //Cache the resolved Bean name and the enhancement on the class, and each Bean is resolved only once classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; beanName=testAspect; } else { this.aspectFactoryCache.put(beanName, factory); //Add cache } advisors.addAll(classAdvisors); // classAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); //Add cache advisors.addAll(this.advisorFactory.getAdvisors(factory)); //③ Get all notifiers } } } this.aspectBeanNames = aspectNames; // this.aspectBeanNames=testAspect,; return advisors; //Finally, return these notifications InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } } } if (aspectNames.isEmpty()) { return Collections.emptyList(); //Returns an empty collection } List<Advisor> advisors = new ArrayList<>(); //Record in cache for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); //Get from the advisors cache if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); //Get the factory method, and then get the advisors from the factory method advisors.addAll(this.advisorFactory.getAdvisors(factory)); //③ Get all notifiers } } return advisors; //Finally, return these notifications } }
Full code: AspectMetadata()
package org.springframework.aop.aspectj.annotation; public class AspectMetadata implements Serializable{ public AspectMetadata(Class<?> aspectClass, String aspectName) { //aspectClass=class com.helloworld.aop.TestAspect;aspectName=testAspect; this.aspectName = aspectName; //Name of section this.aspectName=testAspect; Class<?> currClass = aspectClass; // currClass=class com.helloworld.aop.TestAspect; AjType<?> ajType = null; while (currClass != Object.class) { AjType<?> ajTypeToCheck = AjTypeSystem.getAjType(currClass); if (ajTypeToCheck.isAspect()) { ajType = ajTypeToCheck; break; } currClass = currClass.getSuperclass(); } if (ajType == null) { throw new IllegalArgumentException("Class '" + aspectClass.getName() + "' is not an @AspectJ aspect"); } if (ajType.getDeclarePrecedence().length > 0) { throw new IllegalArgumentException("DeclarePrecendence not presently supported in Spring AOP"); } this.aspectClass = ajType.getJavaClass(); // this.aspectClass=class com.helloworld.aop.TestAspect; this.ajType = ajType; switch (this.ajType.getPerClause().getKind()) { case SINGLETON: this.perClausePointcut = Pointcut.TRUE; // this.perClausePointcut=Pointcut.TRUE; return; case PERTARGET: case PERTHIS: AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(); ajexp.setLocation(aspectClass.getName()); ajexp.setExpression(findPerClause(aspectClass)); ajexp.setPointcutDeclarationScope(aspectClass); this.perClausePointcut = ajexp; return; case PERTYPEWITHIN: // Works with a type pattern this.perClausePointcut = new ComposablePointcut(new TypePatternClassFilter(findPerClause(aspectClass))); return; default: throw new AopConfigException( "PerClause " + ajType.getPerClause().getKind() + " not supported by Spring AOP for " + aspectClass); } } }
Complete code: getAdvisors
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { //aspectInstanceFactory=BeanFactoryAspectInstanceFactory: bean name 'testAspect'; Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); //Get the class object of Aspect() annotation from aspectMetadata aspectClass=class com.helloworld.aop.TestAspect; String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); //Gets the class name of the Aspect() annotation aspectName=testAspect; validate(aspectClass); //verification aspectClass=class com.helloworld.aop.TestAspect; // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = // lazySingletonAspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); //Record in cache for (Method method : getAdvisorMethods(aspectClass)) { // method=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint); method=public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint); method=protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException; method=public boolean java.lang.Object.equals(java.lang.Object); method=protected void java.lang.Object.finalize() throws java.lang.Throwable; method=public final native java.lang.Class java.lang.Object.getClass(); method=public native int java.lang.Object.hashCode(); method=public final native void java.lang.Object.notify(); method=public final native void java.lang.Object.notifyAll(); method=private static native void java.lang.Object.registerNatives(); method=public java.lang.String java.lang.Object.toString(); method=public final void java.lang.Object.wait() throws java.lang.InterruptedException; method=public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException; method=public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException; Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); //Construct InstantiationModelAwarePointcutAdvisorImpl advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (advisor != null) { advisors.add(advisor); //5. Add Advisor object to container advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); //If the looking enhancer is not empty and the enhanced delay initialization is configured, the synchronous instantiation enhancer needs to be added in the first place advisors.add(0, instantiationAdvisor); } // Find introduction fields. for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); //Judge whether there is a DeclareParents annotation on the attribute. If so, return the section if (advisor != null) { advisors.add(advisor); //5. Add Advisor object to container } } return advisors; //Finally, return these notifications InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Complete code: getAdvisor
package org.springframework.aop.aspectj.annotation; public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable{ @Override @Nullable public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, //candidateAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint);aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrderInAspect=0;aspectName=testAspect; int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); //test AspectJExpressionPointcut expressionPointcut = getPointcut( // expressionPointcut=AspectJExpressionPointcut: () pointCut(); candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); // InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } }
Full code: InstantiationModelAwarePointcutAdvisorImpl()
package org.springframework.aop.aspectj.annotation; public class InstantiationModelAwarePointcutAdvisorImpl implements InstantiationModelAwarePointcutAdvisor{ public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, //declaredPointcut=AspectJExpressionPointcut: () pointCut();aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint);aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4;aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect';declarationOrder=0;aspectName=testAspect; Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) { this.declaredPointcut = declaredPointcut; //Tangent expression this.declaredPointcut=AspectJExpressionPointcut: () pointCut(); this.declaringClass = aspectJAdviceMethod.getDeclaringClass(); //Section class this.declaringClass=class com.helloworld.aop.TestAspect; this.methodName = aspectJAdviceMethod.getName(); //The name of the notification method this.methodName=methodBefore; this.parameterTypes = aspectJAdviceMethod.getParameterTypes(); //Notification method parameters this.parameterTypes=interface org.aspectj.lang.JoinPoint,; this.aspectJAdviceMethod = aspectJAdviceMethod; //Notification method this.aspectJAdviceMethod=public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint); this.aspectJAdvisorFactory = aspectJAdvisorFactory; //Advisor factory of aspectJ this.aspectJAdvisorFactory=org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory@420a85c4 ; this.aspectInstanceFactory = aspectInstanceFactory; //Factory class of slice instance this.aspectInstanceFactory=LazySingletonAspectInstanceFactoryDecorator: decorating BeanFactoryAspectInstanceFactory: bean name 'testAspect'; this.declarationOrder = declarationOrder; //Order of sections this.declarationOrder=0; this.aspectName = aspectName; //Name of section this.aspectName=testAspect; if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; // this.pointcut=AspectJExpressionPointcut: () pointCut(); this.lazy = false; // this.lazy=false; this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); //This method focuses on creating an advice object this.instantiatedAdvice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; } } }
Complete code: createBeanInstance
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); //Parsing bean type information beanClass=class com.helloworld.service.impl.UserServiceImpl; if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); //If there is a Supplier callback, the policy is initialized with the given callback method if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); //If there is an instance factory, call the factory method directly } if (mbd.getFactoryMethodName() != null) { //1. If there is a factory method, use the factory method to instantiate the bean object return instantiateUsingFactoryMethod(beanName, mbd, args); //The factory method is used for instantiation. Readers who are not familiar with this concept please see the appendix. Note that it is not FactoryBean } // Shortcut when re-creating the same bean... boolean resolved = false; //Resolved: whether the constructor or factory method has been resolved resolved=false; boolean autowireNecessary = false; //Autowirenecessary: whether automatic injection is required (i.e. whether constructor parameters need to be resolved) autowireNecessary=false; if (args == null) { synchronized (mbd.constructorArgumentLock) { //2. Lock if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; //2.1 if the resolvedconstructorfactorymethod cache is not empty, mark resolved as resolved autowireNecessary = mbd.constructorArgumentsResolved; //2.2 judge whether automatic injection is required according to constructor arguments resolved } } } if (resolved) { if (autowireNecessary) { //3. If it has been resolved, use the resolved constructor method in the resolvedconstructorfactorymethod cache return autowireConstructor(beanName, mbd, null, null); //3.1 if automatic injection is required, execute constructor automatic injection } else { return instantiateBean(beanName, mbd); //6. If there is no special processing, the default constructor is used for bean instantiation } } // Candidate constructors for autowiring? Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); //4. Apply the post processor SmartInstantiationAwareBeanPostProcessor to get the candidate constructor of the bean if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); //5. If ctors is not empty, the injection mode of mbd is autowire_ Constructor | MDB defines the parameter value | args of the constructor. If it is not empty, constructor automatic injection will be executed } // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); //Get the preferred constructor, possibly the default constructor if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); //Constructor auto injection } // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); //6. If there is no special processing, the default constructor is used for bean instantiation org.springframework.beans.BeanWrapperImpl: wrapping object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; } }
Complete code: initializeBean
package org.springframework.beans.factory.support; public class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory{ protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //beanName=userServiceImpl;mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; if (System.getSecurityManager() != null) { //4. Call initialization method AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); //Special bean processing: Aware, BeanClassLoaderAware, beanfactory Aware return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); //Special bean processing: Aware, BeanClassLoaderAware, beanfactory Aware beanName=userServiceImpl; } Object wrappedBean = bean; //Execute the postProcessBeforeInitialization method before the init method method if (mbd == null || !mbd.isSynthetic()) { //Loop through the postProcessBeforeInitialization method of the post processor of those beans mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //2. Apply the postProcessBeforeInitialization method of BeanPostProcessor before initialization to allow the bean instance to be wrapped } try { invokeInitMethods(beanName, wrappedBean, mbd); //3. Call initialization method mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; beanName=userServiceImpl; } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { //Loop through the postProcessBeforeInitialization method of the post processor of those beans mbd=Root bean: class [com.helloworld.service.impl.UserServiceImpl]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [D:\project\helloworld\target\classes\com\helloworld\service\impl\UserServiceImpl.class]; wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); //4. After initialization, the postProcessAfterInitialization method of BeanPostProcessor is applied to allow the bean instance to be wrapped } return wrappedBean; //5. Return wrappedBean } }
Complete code: wrapIfNecessary
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //beanName=userServiceImpl;cacheKey=userServiceImpl; if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //Create proxy if we have advice. Enhanced method acquisition specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //Inserts a value into the proxy collection cacheKey=userServiceImpl; Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); //Agent type cacheKey=userServiceImpl; return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); //Inserts a value into the proxy collection return bean; } }
Full code: findadvisors thatcanapply
package org.springframework.aop.support; public class AopUtils { public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { //candidateAdvisors=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;clazz=class com.helloworld.service.impl.UserServiceImpl; if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); //Define an appropriate enhancer collection object for (Advisor candidate : candidateAdvisors) { // candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); //2 - add notification enhancements } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); //Currently not used, so the value is false hasIntroductions=false; for (Advisor candidate : candidateAdvisors) { // candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (candidate instanceof IntroductionAdvisor) { // already processed continue; } if (canApply(candidate, clazz, hasIntroductions)) { // clazz=class com.helloworld.service.impl.UserServiceImpl; hasIntroductions=false; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; clazz=class com.helloworld.service.impl.UserServiceImpl; hasIntroductions=false; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; eligibleAdvisors.add(candidate); //2 - add notification enhancements candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; candidate=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; } } return eligibleAdvisors; // InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; } }
Full code: canApply
package org.springframework.aop.support; public class AopUtils { public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { //pc=AspectJExpressionPointcut: () pointCut();targetClass=class com.helloworld.service.impl.UserServiceImpl;hasIntroductions=false; Assert.notNull(pc, "Pointcut must not be null"); // pc=AspectJExpressionPointcut: () pointCut(); if (!pc.getClassFilter().matches(targetClass)) { return false; } MethodMatcher methodMatcher = pc.getMethodMatcher(); //Gets the tangent point method matching object, which is used to match whether the method conforms to methodMatcher=AspectJExpressionPointcut: () pointCut(); if (methodMatcher == MethodMatcher.TRUE) { // No need to iterate the methods if we're matching any method anyway... return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; //Special type, which is used for down conversion. It belongs to this type generated by Aspect if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; // introductionAwareMethodMatcher=AspectJExpressionPointcut: () pointCut(); } Set<Class<?>> classes = new LinkedHashSet<>(); //Find all interfaces implemented by the current class and its ancestor classes if (!Proxy.isProxyClass(targetClass)) { // targetClass=class com.helloworld.service.impl.UserServiceImpl; classes.add(ClassUtils.getUserClass(targetClass)); //Join the collection } classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); //Add judgment to all interfaces of the class. It's better to judge wrong here than miss it for (Class<?> clazz : classes) { // clazz=class com.helloworld.service.impl.UserServiceImpl; Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); //Get all Method objects of the current class through reflection methods=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo),protected void java.lang.Object.finalize() throws java.lang.Throwable,public final void java.lang.Object.wait() throws java.lang.InterruptedException,public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException,public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException,public boolean java.lang.Object.equals(java.lang.Object),public java.lang.String java.lang.Object.toString(),public native int java.lang.Object.hashCode(),public final native java.lang.Class java.lang.Object.getClass(),protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException,public final native void java.lang.Object.notify(),public final native void java.lang.Object.notifyAll(),private static native void java.lang.Object.registerNatives(),; for (Method method : methods) { //Get all methods of the interface method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { // targetClass=class com.helloworld.service.impl.UserServiceImpl; method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); hasIntroductions=false; return true; } } } return false; } }
Complete code: createProxy
package org.springframework.aop.framework.autoproxy; public class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor{ protected Object createProxy(Class<?> beanClass, @Nullable String beanName, //beanClass=class com.helloworld.service.impl.UserServiceImpl;beanName=userServiceImpl;specificInterceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,;targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]; @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); //Expose the target class and save it in BeanDefinition beanName=userServiceImpl; beanClass=class com.helloworld.service.impl.UserServiceImpl; } ProxyFactory proxyFactory = new ProxyFactory(); //Create a new agent factory and copy the relevant configuration properties in the current class for it proxyFactory=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 0 advisors []; targetSource [EmptyTargetSource: no target class, static]; proxyTargetClass=false; optimize=false; opaque=false; exposeProxy=false; frozen=false; proxyFactory.copyFrom(this); //Gets the related properties in the current class if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); //Agent factory setting agent target class } else { evaluateProxyInterfaces(beanClass, proxyFactory); //Otherwise, a proxy is created based on the interface } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); //Encapsulate interceptors as notifications advisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; proxyFactory.addAdvisors(advisors); //Add intensifier advisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; proxyFactory.setTargetSource(targetSource); //Set the class to proxy targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a ]; customizeProxyFactory(proxyFactory); //Subclass custom agent proxyFactory=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; proxyFactory.setFrozen(this.freezeProxy); //It is used to control whether the modification notification is allowed after the agent factory is configured. The default value is false (indicating that modification is not allowed) if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); //It has been filtered } return proxyFactory.getProxy(getProxyClassLoader()); //Create proxy } }
Complete code: createAopProxy
package org.springframework.aop.framework; public class DefaultAopProxyFactory implements AopProxyFactory{ @Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { //config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { // config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; Class<?> targetClass = config.getTargetClass(); //Gets the class that needs to be proxied targetClass=class com.helloworld.service.impl.UserServiceImpl; 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() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); //Create JDK dynamic AOP proxy object } return new ObjenesisCglibAopProxy(config); //Otherwise, use CGLIB proxy } else { return new JdkDynamicAopProxy(config); //Create JDK dynamic AOP proxy object } } }
Complete code: getProxy
package org.springframework.aop.framework; public class CglibAopProxy implements AopProxy{ @Override public Object getProxy(@Nullable ClassLoader classLoader) { if (logger.isTraceEnabled()) { //1. Loop PropertySources logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource()); } try { Class<?> rootClass = this.advised.getTargetClass(); //Get the class to be represented rootClass=class com.helloworld.service.impl.UserServiceImpl; Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy"); Class<?> proxySuperClass = rootClass; //The parent class of the proxy object (cglib creates the proxy object by inheritance, so the proxy class is used as the parent class of the proxy object) proxySuperClass=class com.helloworld.service.impl.UserServiceImpl; if (ClassUtils.isCglibProxyClass(rootClass)) { proxySuperClass = rootClass.getSuperclass(); Class<?>[] additionalInterfaces = rootClass.getInterfaces(); //Add the interface to be proxied for (Class<?> additionalInterface : additionalInterfaces) { this.advised.addInterface(additionalInterface); } } // Validate the class, writing log messages as necessary. validateClassIfNecessary(proxySuperClass, classLoader); //Verify it proxySuperClass=class com.helloworld.service.impl.UserServiceImpl; // Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); //Remove unnecessary code if (classLoader != null) { //2.targetTypeName is not empty and classLoader is not null enhancer.setClassLoader(classLoader); //Set classLoader if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); //Sets the class to inherit from proxySuperClass=class com.helloworld.service.impl.UserServiceImpl; enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); //Set its interface enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); //Set naming policy enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); //Set the bytecode generation strategy, which is set to ClassLoaderAwareUndeclaredThrowableStrategy to encapsulate the DefaultGeneratorStrategy Callback[] callbacks = getCallbacks(rootClass); //Generate the required callback, that is, write our advisor into the class that implements MethodInterceptor according to certain rules callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e ,; Class<?>[] types = new Class<?>[callbacks.length]; //Create the corresponding callback for each location, mainly using proxycallback filter to decide which callback to call for (int x = 0; x < types.length; x++) { // x=0; x=1; x=2; x=3; x=4; x=5; x=6; types[x] = callbacks[x].getClass(); // types[x]=class org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor; types[x]=class org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor; types[x]=class org.springframework.aop.framework.CglibAopProxy$SerializableNoOp; types[x]=class org.springframework.aop.framework.CglibAopProxy$StaticDispatcher; types[x]=class org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher; types[x]=class org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor; types[x]=class org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor; } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); //Set callback type types=class org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor,class org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor,class org.springframework.aop.framework.CglibAopProxy$SerializableNoOp,class org.springframework.aop.framework.CglibAopProxy$StaticDispatcher,class org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher,class org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor,class org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor,; // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); //Create and return a proxy class } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() + ": Common causes of this problem include using a final class or a non-visible class", ex); } catch (Throwable ex) { // TargetSource.getTarget() failed throw new AopConfigException("Unexpected AOP exception", ex); } } }
Complete code: createProxyClassAndInstance
package org.springframework.aop.framework; public class ObjenesisCglibAopProxy extends CglibAopProxy{ @Override @SuppressWarnings("unchecked") protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) { //callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e,; Class<?> proxyClass = enhancer.createClass(); //① The proxy class is generated proxyClass=class com.helloworld.service.impl.UserServiceImpl$$EnhancerBySpringCGLIB$9344f1; Object proxyInstance = null; if (objenesis.isWorthTrying()) { try { proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache()); //If spring is not configured objenesis. Ignore, a proxy implementation is created } catch (Throwable ex) { logger.debug("Unable to instantiate proxy using Objenesis, " + "falling back to regular proxy construction", ex); } } if (proxyInstance == null) { // Regular instantiation via default constructor... try { Constructor<?> ctor = (this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor()); ReflectionUtils.makeAccessible(ctor); //Set the construction method to accessible proxyInstance = (this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance()); } catch (Throwable ex) { throw new AopConfigException("Unable to instantiate proxy using Objenesis, " + "and regular proxy instantiation via default constructor fails as well", ex); } } ((Factory) proxyInstance).setCallbacks(callbacks); // callbacks=org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor@101639ae,org.springframework.aop.framework.CglibAopProxy$StaticUnadvisedInterceptor@4c550889,org.springframework.aop.framework.CglibAopProxy$SerializableNoOp@1d2bd371,org.springframework.aop.framework.CglibAopProxy$StaticDispatcher@44040454,org.springframework.aop.framework.CglibAopProxy$AdvisedDispatcher@65fe9e33,org.springframework.aop.framework.CglibAopProxy$EqualsInterceptor@18bc345,org.springframework.aop.framework.CglibAopProxy$HashCodeInterceptor@42f8285e,; return proxyInstance; } }