All articles
https://www.cnblogs.com/lay2017/p/11478237.html
text
two core spring is ioc and aop. In about ioc dependency injection article, we learned how to create Bean according to BeanDefinition, and then deal with @Autowired @Resource two notes in BeanPostProcessor, the automatic injection Bean.
This article will explain another piece of the core content, aop section.
AOP auto-configuration
First, aop section based on the auto-configuration springboot. If you do not understand the automatic configuration, refer to the autoconfiguration mechanism article.
To this end, we first find the class AopAutoConfiguration aop autoconfiguration
@Configuration @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class }) @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) public class AopAutoConfiguration { @Configuration @EnableAspectJAutoProxy(proxyTargetClass = false) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) public static class JdkDynamicAutoProxyConfiguration { } @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) public static class CglibAutoProxyConfiguration { } }
We will understand Cglib as the main object, you can see a @EnableAspectJAutoProxy comment on CglibAutoProxyConfiguration, it means open proxy section, we open the annotation
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { // }
We see, @ Import annotation imported AspectJAutoProxyRegistrar. In the article automatically configured , we learned ConfigurationClassParser will deal @Import comment. Here we are no longer concerned about how to deal with @Import annotations directly open class look AspectJAutoProxyRegistrar
class AspectJAutoProxyRegistrar the implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions (AnnotationMetadata importingClassMetadata, the BeanDefinitionRegistry Registry) { // Register the agent automatically cut creator AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary (Registry); // omitted } }
Follow registerAspectJAnnotationAutoProxyCreatorIfNecessary
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); }
Continue to follow up registerAspectJAnnotationAutoProxyCreatorIfNecessary
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
We see that call registerOrEscalateApcAsRequired method specifies a class AnnotationAwareAspectJAutoProxyCreator, this class will create a proxy class
Follow registerOrEscalateApcAsRequired method
private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { // // 构建BeanDefinition RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 注册到Bean容器 registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
We can see, eventually registered to Bean containers as BeanDefinition exist. We can think aop automatic configuration process is to create BeanDefinition AnnotationAwareAspectJAutoProxyCreator this class.
Registration AnnotationAwareAspectJAutoProxyCreator
First, let's take a look at the inheritance structure AnnotationAwareAspectJAutoProxyCreator
We can see, AnnotationAwareAspectJAutoProxyCreator ultimately realized BeanPostProcessor, BeanPostProcessor that is when it is created as Bean?
Here, we have to return refresh method refresh container process, follow the refresh method AbstractApplicationContext
public void Refresh () throws BeansException, {IllegalStateException the synchronized ( the this .startupShutdownMonitor) { // the try { // // Register BeanDefinition container invokeBeanFactoryPostProcessors (beanFactory); // Sign post processor container registerBeanPostProcessors (beanFactory); // } // } }
After registration BeanDefinition, it will be converted to the BeanPostProcessor of BeanDefinition Bean registered with the container. After the end of registerBeanPostProcessors, AnnotationAwareAspectJAutoProxyCreator exists in the form of Bean in the BeanFactory.
Trigger AnnotationAwareAspectJAutoProxyCreator
Next, we look at AnnotationAwareAspectJAutoProxyCreator after being registered as Bean, is in what position is triggered. Front, IOC dependency injection article we mentioned createBean method, Bean will be created according to BeanDefinition.
Follow createBean method of AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // try { // BeanPostProcessors 调用 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // try { // 创建实例对象 Object beanInstance = doCreateBean(beanName, mbdToUse, args); // return beanInstance; } // }
We see before doCreateBean, triggering resolveBeforInstantiation first method, called AnnotationAwareAspectJAutoProxyCreator.
Analytical section
Follow resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); // } } // } return bean; }
Continue to follow up applyBeanPostProcessorBeforeInstantiation method
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 触发postProcesBeforeInstantiation Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
Continue postProcessBeforeInstantiation method of follow up AbstractAutoProxyCreator
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { // if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } // return null; }
isInfrastructureCLass returns false, follow AspectJAwareAdvisorAutoProxyCreator of shouldSkip
protected boolean shouldSkip(Class<?> beanClass, String beanName) { // 返回所有的通知,如@Before @After @AfterThrowing @Round List<Advisor> candidateAdvisors = findCandidateAdvisors(); for (Advisor advisor : candidateAdvisors) { if (advisor instanceof AspectJPointcutAdvisor && ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) { return true; } } return super.shouldSkip(beanClass, beanName); }
Here findCandidateAdvisors method will be obtained from beanFactory class metadata annotations @Aspect then acquired defined therein Advisor.
At this point, we have received complete analytical work cut parts.
Agent enhancements
Back AbstractAutowireCapableBeanFactory method of createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // try { // BeanPostProcessors 调用 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } // try { // 创建实例对象 Object beanInstance = doCreateBean(beanName, mbdToUse, args); // return beanInstance; } // }
Acquired Advisor, then take a look Advisor is enhanced to process the Bean, follow doCreateBean
protected Object doCreateBean ( Final String the beanName, Final RootBeanDefinition MBD, Final @Nullable Object [] args) throws BeanCreationException { // IF (instanceWrapper == null ) { // create an instance instanceWrapper = createBeanInstance (the beanName, MBD, args); } // Object exposedObject = the bean; the try { // automatic injector populateBean (the beanName, MBD, instanceWrapper); // initialize Bean, create inlet agent exposedObject = initializeBean(beanName, exposedObject, mbd); } // return exposedObject; }
We find initializeBean, this initialization Bean's entrance, began to focus on enhancing agent part from here, follow initializeBean method
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
Continue to follow up applyBeanPostProcessorsAfterInitialization method
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
postProcessAfterInitialization method will be called AbstractAutoProxyCreator here, and follow-up method
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
Continue to follow up wrapIfNecessary
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { // // 获取适用于当前Bean的Advisors Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建代理 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
getAdvicesAndAdvisorsForBean method will get to enhance the Advisor to the Bean, and then createProxy will create a proxy class, and all the way to return, if it is a singleton, then registered into the cache
Creating an agent to follow up to see createProxy
protected Object createProxy (<?> Class beanClass, the beanName @Nullable String, @Nullable Object [] specificInterceptors, the TargetSource TargetSource) { // // Get Available Advisor Advisor [] = Advisors buildAdvisors (the beanName, specificInterceptors); proxyFactory.addAdvisors ( Advisors); // // create and return a proxy object return proxyFactory.getProxy (getProxyClassLoader ()); }
Follow getProxy
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
createAopProxy will return Cglib implemented or the implementation jdk dynamic proxy according to the conditions, then call them getProxy way to get a proxy object
to sum up
Many details of the omitted herein, is generally from logic: aop autoconfiguration -> Analytical @Aspect aspect instance -> reinforcing agents, such drafting of a logic.
The core is automatically configured to import a AnnotationAwareAspectJAutoProxyCreator, which implements the BeanPostProcessor. So before you create the Bean instance of an object triggers resolve @Aspect cut objects to acquire Advisor. After generating the Bean instance of an object, it will then trigger the analytical results of the class before the agent to enhance Bean instance of an object, enhanced Advisor from. Acting enhanced realize there cglib and jdk dynamic proxy two kinds.
Finally, through enhanced if the agent Bean is singleton, as before, will be added to the cache object.