原文网址:Spring(SpringBoot)--AOP的原理(二)--源码分析_IT利刃出鞘的博客-CSDN博客
说明
本文通过源码来分析Spring的AOP的原理。
相关网址
Spring(SpringBoot)--AOP的原理(一)--概述_IT利刃出鞘的博客-CSDN博客_springboot的aop原理
简介
spring-boot-starter-aop如何做到自动配置的?见:SpringBoot原理--自动配置_feiying0canglang的博客-CSDN博客
要使用AOP,首先要引入包。如果引入的是spring-aop包,则需要使用@EnableAspectJAutoProxy开启aop功能;如果引入的是spring-boot-starter-aop,则AOP就直接可以用了,无需加注解之类的开启它。
实际上,spring-boot-starter-aop是自动用了@EnableAspectJAutoProxy,所以我们还是从@EnableAspectJAutoProxy开始。
EnableAspectJAutoProxy注解类上用了: @Import({AspectJAutoProxyRegistrar.class})
- @Target({ElementType.TYPE})
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- @Import({AspectJAutoProxyRegistrar.class})
- public @interface EnableAspectJAutoProxy {
- boolean proxyTargetClass() default false;
-
- boolean exposeProxy() default false;
- }
proxyTargetClass 指定是否使用CGLIB的方式创建实现接口的目标对象的代理。缺省值为true,使用CGLIB方式创建对象的代理。
exposeProxy 标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。
总结
AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar,实现registerBeanDefinitions方法
向容器中注册bean:org.springframework.aop.config.internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
追踪:AspectJAutoProxyRegistrar#registerBeanDefinitions //从名字就可以看出来,它是注册BeanDefinition用的。
registerBeanDefinitions //AspectJAutoProxyRegistrar
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //AspectJAutoProxyRegistrar.java
registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)null); //AopConfigUtils.class
registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); //AopConfigUtils.class
AopConfigUtils#registerOrEscalateApcAsRequired
- private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
- Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
- if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
- BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
- if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
- int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
- int requiredPriority = findPriorityForClass(cls);
- if (currentPriority < requiredPriority) {
- apcDefinition.setBeanClassName(cls.getName());
- }
- }
-
- return null;
- } else {
- RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
- beanDefinition.setSource(source);
- beanDefinition.getPropertyValues().add("order", -2147483648);
- beanDefinition.setRole(2);
- registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
- return beanDefinition;
- }
- }
开始的时候AutoProxyCreator类不存在,RootBeanDefinition初始化AnnotationAwareAspectJAutoProxyCreator类,注册类到IOC容器。
相关网址
总结
AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),它在registerBeanPostProcessors()中处理,最终被实例化、设置属性、初始化。
分析
在上边“重要的类”可以得出:AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor接口与Ordered接口(值为32位int的最大值),那它会在registerBeanPostProcessors()中处理:
AbstractApplicationContext#refresh()
registerBeanPostProcessors(beanFactory) //AbstractApplicationContext
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
getBean(String name, Class<T> requiredType) //AbstractBeanFactory
doGetBean(name, requiredType, null, false) //AbstractBeanFactory
createBean(beanName, mbd, args); //AbstractAutowireCapableBeanFactory
doCreateBean(beanName, mbdToUse, args); //AbstractAutowireCapableBeanFactory
AbstractAutowireCapableBeanFactory#doCreateBean(beanName, mbdToUse, args); 主要做了如下几件事:
创建bean :createBeanInstance(beanName, mbd, args)
给bean中的属性赋值:populateBean(beanName, mbd, instanceWrapper)
初始化bean:initializeBean(beanName, exposedObject, mbd)
- protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
- throws BeanCreationException {
-
- // Instantiate the bean.
- // 实例化bean
- BeanWrapper instanceWrapper = null;
- if (mbd.isSingleton()) {
- instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
- }
- if (instanceWrapper == null) {
- instanceWrapper = createBeanInstance(beanName, mbd, args);
- }
- final Object bean = instanceWrapper.getWrappedInstance();
- Class<?> beanType = instanceWrapper.getWrappedClass();
- if (beanType != NullBean.class) {
- mbd.resolvedTargetType = beanType;
- }
-
- // Allow post-processors to modify the merged bean definition.
- // 允许post-processors来修改合并的bean定义
- synchronized (mbd.postProcessingLock) {
- if (!mbd.postProcessed) {
- try {
- applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
- } catch (Throwable ex) {
- throw new BeanCreationException(mbd.getResourceDescription(), beanName,
- "Post-processing of merged bean definition failed", ex);
- }
- 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 &&
- isSingletonCurrentlyInCreation(beanName));
- if (earlySingletonExposure) {
- if (logger.isTraceEnabled()) {
- logger.trace("Eagerly caching bean '" + beanName +
- "' to allow for resolving potential circular references");
- }
- addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
- }
-
- // Initialize the bean instance.
- // 初始化bean
- Object exposedObject = bean;
- try {
- populateBean(beanName, mbd, instanceWrapper);
- exposedObject = initializeBean(beanName, exposedObject, mbd);
- }
- 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) {
- Object earlySingletonReference = getSingleton(beanName, false);
- if (earlySingletonReference != null) {
- if (exposedObject == bean) {
- exposedObject = earlySingletonReference;
- } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
- String[] dependentBeans = getDependentBeans(beanName);
- Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
- for (String dependentBean : dependentBeans) {
- if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
- actualDependentBeans.add(dependentBean);
- }
- }
- 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 " +
- "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
- }
- }
- }
- }
-
- // Register bean as disposable.
- try {
- registerDisposableBeanIfNecessary(beanName, bean, mbd);
- } catch (BeanDefinitionValidationException ex) {
- throw new BeanCreationException(
- mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
- }
-
- return exposedObject;
- }