Spring AOP 源码解析

AOP中的几个概念

Advisor 和 Advice

Advice,我们通常都会把他翻译为通知,其实很不好理解,其实他还有另外一个意思,就是“建议”,我觉得把Advice理解为“建议”会更好。

比如,我们已经完成了一个功能,这时客户跟我们说,我建议在这个功能之前可以再增加一些逻辑,再之后再增加一些逻辑。

在Spring中,Advice分为:

  1. 前置Advice:MethodBeforeAdvice
  2. 后置Advice:AfterReturningAdvice
  3. 环绕Advice:MethodInterceptor
  4. 异常Advice:ThrowsAdvice

在利用Spring AOP去生成一个代理对象时,我们可以设置这个代理对象的Advice。

而对于Advice来说,它只表示了“建议”,它没有表示这个“建议”可以用在哪些方面。

就好比,我们已经完成了一个功能,客户给这个功能提了一个建议,但是这个建议也许也能用到其他功能上。

这时,就出现了Advisor,表示一个Advice可以应用在哪些地方,而“哪些地方”就是Pointcut(切点)。

Pointcut

切点,表示我想让哪些地方加上我的代理逻辑。

比如某个方法,

比如某些方法,

比如某些方法名前缀为“find”的方法,

比如某个类下的所有方法,等等。

在Pointcut中,有一个MethodMatcher,表示方法匹配器。

使用ProxyFactory通过编程创建AOP代理

首先得明白动态代理:JDK动态代理和CGLIB技术,有兴趣的自己谷歌百度建一个例子了解一下

ProxyFactory的工作原理

ProxyFactory就是一个代理对象生产工厂,在生成代理对象之前需要对代理工厂进行配置。

ProxyFactory在生成代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术:

// config就是ProxyFactory对象

// optimize为true,或proxyTargetClass为true,或用户没有给ProxyFactory对象添加interface
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    Class<?> targetClass = config.getTargetClass();
    if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: " +
                "Either an interface or a target is required for proxy creation.");
    }
    // targetClass是接口,直接使用Jdk动态代理
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
        return new JdkDynamicAopProxy(config);
    }
    // 使用Cglib
    return new ObjenesisCglibAopProxy(config);
}
else {
    // 使用Jdk动态代理
    return new JdkDynamicAopProxy(config);
}

jdk动态代理和cglib对比

动态代理cglibjdk
是否提供子类代理
是否提供接口代理
区别必须依赖于CGLib的类库,但是它需要类来实现任何接口代理的是指定的类生成一个子类,覆盖其中的方法实现InvocationHandler,使用Proxy.newProxyInstance产生代理对象,被代理的对象必须要实现接口
Cglib和jdk动态代理的区别?

1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
2、 Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理

什么时候用cglib什么时候用jdk动态代理?

1、目标对象生成了接口 默认用JDK动态代理
2、如果目标对象使用了接口,可以强制使用cglib
3、如果目标对象没有实现接口,必须采用cglib库,Spring会自动在JDK动态代理和cglib之间转换

JDK动态代理和cglib字节码生成的区别?

1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类
2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的

AOP作用的类,什么时候生成动态代理类

测试代码:

@Aspect
@Component
public class Audience {
	/**
	 * 表演之前,观众就座
	 */
	@Before("execution(* com.luban.service.UserService.test())")
	public void takeSeats() {
		System.out.println("Taking seats");
	}

	/**
	 * 表演之前,将手机调至静音
	 */
	@After("execution(* com.luban.service.UserService.test())")
	public void silenceCellPhones() {
		System.out.println("Silencing cell phones");
	}

}
@Component
public class UserService implements InitializingBean, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware , ApplicationContextAware {


//	@Autowired
//	private Test test;

//	@Resource
//	private Test testExtends;

	@Override
	public void afterPropertiesSet() throws Exception {
//		System.out.println("BeanNameAware.afterPropertiesSet()-------------");
	}

	public void test() {
		System.out.println("test");
	}

	@Override
	public void setBeanName(String name) {
//		System.out.println("----BeanClassLoaderAware.setBeanClassLoader---");

	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
//		System.out.println("----BeanClassLoaderAware.setBeanClassLoader---");
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
//		System.out.println("----BeanFactoryAware.setBeanFactory---");
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//		System.out.println("----EnvironmentAware.setApplicationContext---");
	}

	@Override
	public void setEmbeddedValueResolver(StringValueResolver resolver) {
//		System.out.println("----EmbeddedValueResolverAware.setEmbeddedValueResolver----");

	}

	@Override
	public void setEnvironment(Environment environment) {
//		System.out.println("----ApplicationContextAware.setEnvironment----");

	}
}

忽略多余的代码,上面aop切入的就是test()方法

public class Test {

	public static void main(String[] args) {

		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//		TestBeanFactoryPostProcessor testBeanFactoryPostProcessor = new TestBeanFactoryPostProcessor();//要在实例化之前加入,还没找到怎么加入
//		applicationContext.addBeanFactoryPostProcessor(testBeanFactoryPostProcessor);
		UserService userService = applicationContext.getBean("userService", UserService.class);
		userService.test();
	}
}

利用debug模式打上断点,前面的文章已经说明怎么创建单例bean的实例,因为我们aop切入的是UserService类,我们现在主要的目的是找到在单例池里面UserService实例的变化,首先在bean初始化的那里打上debug断点:

在还没有执行初始化之前传入的UserService实例是UserService@2018,然后执行完该方法。

UserService的Bean实例已经变成了一个代理的类,咱们在来看里面做了什么操作:

if (mbd == null || !mbd.isSynthetic()) {
			// 4.4、初始化后 AOP  ()
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
@Override
	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;
	}

在这个方法里面上面的代码是执行初始化后的BeanPostProcessor后置处理去的postProcessAfterInitialization方法,AOP代理就是在这里面实现的,继续进入该方法:

getBeanPostProcessors()是获取bean工厂缓存的BeanPostProcessors后置处理器

有很多后置处理器在前面的章节我已经分析过了,咱们就不分析了,主要看上面第四个后置处理器AbstractAutoProxyCreator的后置方法是怎么操作的:

	@Override
	// 正常情况进行AOP的地方
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			// earlyProxyReferences中存的是哪些提前进行了AOP的bean,beanName:AOP之前的对象
			// 注意earlyProxyReferences中并没有存AOP之后的代理对象  BeanPostProcessor
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				// 没有提前进行过AOP,则进行AOP
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		// 为什么不返回代理对象呢?
		return bean;   //
	}
	protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		// 在当前targetSourcedBeans中存在的bean,表示在实例化之前就产生了代理对象
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		// 当前这个bean不用被代理
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}

		// 先判断当前bean是不是要进行AOP,比如当前bean的类型是Pointcut、Advice、Advisor等那就不需要进行AOP
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// Create proxy if we have advice.
		// 获取当前beanClass所匹配的advisors
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

		// 如果匹配的advisors不等于null,那么则进行代理,并返回代理对象
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 基于bean对象和Advisor创建代理对象
			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;
	}

这个方法的逻辑是:

1.在当前targetSourcedBeans中存在的bean,表示在实例化之前就产生了代理对象

2.当前这个bean不用被代理(其实就是这个类advisedBeans缓存里面去查)

3.先判断当前bean是不是要进行AOP,比如当前bean的类型是Pointcut、Advice、Advisor等那就不需要进行AOP

4.获取当前beanClass所匹配的advisors

5.如果匹配的advisors不等于null,那么则进行代理,并返回代理对象(这里会给这个类里面advisedBeans和proxyTypes属性缓存期当前被代理的类)

这里面有三个切入的点,第一个还不明白是什么东西,其余两个是自己写的切入方法。

6.

	// 基于bean对象和Advisor创建代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);	// 复制配置参数
		// 是否指定了必须用cglib进行代理
		if (!proxyFactory.isProxyTargetClass()) {
			// 如果没有指定,那么则判断是不是应该进行cglib代理(判断BeanDefinition中是否指定了要用cglib)
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				// 是否进行jdk动态代理,如果当前beanClass实现了某个接口,那么则会使用JDK动态代理
				evaluateProxyInterfaces(beanClass, proxyFactory); // 判断beanClass有没有实现接口
			}
		}


		// 将commonInterceptors和specificInterceptors整合再一起
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

		proxyFactory.addAdvisors(advisors);	// 向ProxyFactory中添加advisor
		proxyFactory.setTargetSource(targetSource); // 被代理的对象
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);	//
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		// 生成代理对象
		return proxyFactory.getProxy(getProxyClassLoader());
	}

这一步就很清楚了,判断用哪一种了代理模式去代理,然后利用ProxyFactory创建代理对象。

所以由上面可以知道:

总结:bean如果被代理了,则在初始化的时候,初始化后利用BeanPostProcessors后置处理器的postProcessAfterInitialization方法进行动态代理。

最后执行完方法,看控制台输出:

在测试main里面getBean取得就是代理类,然后走就是代理得方法。

到这一步我们已经知道aop是怎么生成动态代理类然后进行切入的,但是有一个问题:

AbstractAutoProxyCreator是什么时候加入BeanPostProcessors,那就是下面的要分析的地方了

AbstractAutoProxyCreator是什么时候加入beanFactory的BeanPostProcessors缓存里面的

利用debug模式从创建new AnnotationConfigApplicationContext(AppConfig.class);开始监听:

((DefaultListableBeanFactory)((AnnotationConfigApplicationContext)this).beanFactory)

.beanPostProcessors

查看AbstractAutoProxyCreator是什么时候加入的:

// Invoke factory processors registered as beans in the context.
				// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
				// 默认情况下:
				// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
				// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
				// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
				// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
				invokeBeanFactoryPostProcessors(beanFactory);  //BeanDefinitionRegistryPostProcessor ,BeanFactoryPostProcessors

				// Register bean processors that intercept bean creation.
				// 从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中
				registerBeanPostProcessors(beanFactory);
invokeBeanFactoryPostProcessors扫苗得到所有beanDefinitionMap里面就存在audience,自己写的Aop类,而registerBeanPostProcessors从BeanFactory找出扫描得到得BeanPostProcessor,实例化并注册到BeanFactory中,AbstractAutoProxyCreator就是在这里面加入的,继续进入该方法,查看是怎么注册进去的:
	protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		// 获取BeanPostProcessor类型的bean
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// Register BeanPostProcessorChecker that logs an info message when
		// a bean is created during BeanPostProcessor instantiation, i.e. when
		// a bean is not eligible for getting processed by all BeanPostProcessors.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {  //PriorityOrdered  PriorityOrdered  @Order  @Priority
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 把priorityOrderedPostProcessors添加到beanFactory中
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 把orderedPostProcessors添加到beanFactory中
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

这里就是排序后然后注册到beanFactory.addBeanPostProcessor()

List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
   BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   nonOrderedPostProcessors.add(pp);
   if (pp instanceof MergedBeanDefinitionPostProcessor) {
      internalPostProcessors.add(pp);
   }
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

而AbstractAutoProxyCreator就是在这段代码里面注册进去的,他是存到internalPostProcessors集合里面的,翻译解释

到这里我们已经知道它是怎么注册进去的,但是有个问题,它是多久存在beanDefinitionNames里面的

继续利用debug模式监听beanDefinitionNames可以知道在invokeBeanFactoryPostProcessors()扫面过后就存在,咱们继续跟踪它是怎么加载进去,由于前面我已经分析过这个方法,咱们直接跳到关键点:

在这个方法里面会去利用ConfigurationClassParser类型处理扫面的类型的一些类型信息,然后生成一个元数据对象(具体后面分析),而这里面有个方法就是处理@Import注解

	private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
			Collection<SourceClass> importCandidates, boolean checkForCircularImports) {

		if (importCandidates.isEmpty()) {
			return;
		}

		if (checkForCircularImports && isChainedImportOnStack(configClass)) {
			this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
		}
		else {
			this.importStack.push(configClass);
			try {
				for (SourceClass candidate : importCandidates) {
					if (candidate.isAssignable(ImportSelector.class)) {
						// Candidate class is an ImportSelector -> delegate to it to determine imports
						Class<?> candidateClass = candidate.loadClass();
						ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
								this.environment, this.resourceLoader, this.registry);
						if (selector instanceof DeferredImportSelector) {
							this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
						}
						else {
							String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
							Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
							processImports(configClass, currentSourceClass, importSourceClasses, false);
						}
					}
					else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						// 如果@Import注解中的类实现了ImportBeanDefinitionRegistrar接口,就把该类的实例放入importBeanDefinitionRegistrars中,
						// 后面再执行该实例的registerBeanDefinitions方法
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}
					else {
						// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
						// process it as an @Configuration class
						this.importStack.registerImport(
								currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
						processConfigurationClass(candidate.asConfigClass(configClass));
					}
				}
			}
			catch (BeanDefinitionStoreException ex) {
				throw ex;
			}
			catch (Throwable ex) {
				throw new BeanDefinitionStoreException(
						"Failed to process import candidates for configuration class [" +
						configClass.getMetadata().getClassName() + "]", ex);
			}
			finally {
				this.importStack.pop();
			}
		}
	}

而这一段代码就是加入有@Import的信息:

else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
						// Candidate class is an ImportBeanDefinitionRegistrar ->
						// delegate to it to register additional bean definitions
						// 如果@Import注解中的类实现了ImportBeanDefinitionRegistrar接口,就把该类的实例放入importBeanDefinitionRegistrars中,
						// 后面再执行该实例的registerBeanDefinitions方法
						Class<?> candidateClass = candidate.loadClass();
						ImportBeanDefinitionRegistrar registrar =
								ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
										this.environment, this.resourceLoader, this.registry);
						configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
					}

而ImportBeanDefinitionRegistrar.registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator)

后面会根据@Import的信息注入相应的beanDefinition

往上面看for循环的的信息:

可以知道AppConfig有两个@Import信息,而org.springframework.context.annotation.AspectJAutoProxyRegistrar

就是开启aop的注解啊!!!

所以我们回到AppConfig类上查看:

@ComponentScan(value = "com.luban")
@MapperScan
@EnableAspectJAutoProxy
public class AppConfig {}

可以看到我标注了@EnableAspectJAutoProxy注解,但是是不是没有看到@Import的注解,咱们在进入@EnableAspectJAutoProxy注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {}
@Import(AspectJAutoProxyRegistrar.class)这个不就是@Import引入的嘛,

所以我大胆的猜测:Spring同过扫面得到所有的类的元数据信息,并且循环去扫面标注在类上的注解,把含有@Import注解的信息封装到ConfigurationClass的属性importBeanDefinitionRegistrars里面,后续进行注册beanDefinition时候把@Import引入的beanDefinition加入到bean工厂!

下面我们再来看aop的后置处理器是怎么加入到Bean工厂的

其实上面扫描出类的元数据信息,继续下面就是注册beanDefinition:

上面的方法处理其实就是在ConfigurationClassPostProcessor.processConfigBeanDefinitions(BeanDefinitionRegistry registry)

方法里面

			// 对配置BeanDefinition进行解析,解析完后会生成ConfigurationClass
			parser.parse(candidates);   //AppConfig.class
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}

			// 利用reader解析ConfigurationClass,同时注册BeanDefinition
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

上面这段代码就是,先去扫描得到元数据信息,然后在利用

// 利用reader解析ConfigurationClass,同时注册BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
注册BeanDefinition
	public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
		TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
		for (ConfigurationClass configClass : configurationModel) {
			loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
		}
	}

可以看到configurationModel就是扫描出来的配置类,我们直接跳到

ConfigurationClass: beanName 'appConfig', com.luban.AppConfig的

loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
	private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();
			if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
				this.registry.removeBeanDefinition(beanName);
			}
			this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
			return;
		}

		// 当前配置类是不是通过@Import注解导入进来的,如果是则解析该类上面的比如@Scope,@Lazy这些注解信息
		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
		}
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

		// 从配置类中Import进来的资源文件中加载BeanDefinition,比如xml文件
		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		// 调用ImportBeanDefinitionRegistrar对象的registerBeanDefinitions方法加载BeanDefinition
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
		registrars.forEach((registrar, metadata) ->
				registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
	}

这个就是我们上面通过@Import加入配置类的信息

跳到:AspectJAutoProxyRegistrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator)

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}
AspectJAutoProxyRegistrar类实现ImportBeanDefinitionRegistrar,而ImportBeanDefinitionRegistrar是通过判断@Import到入的类是否candidate.isAssignable(ImportBeanDefinitionRegistrar.class)从而在
registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)注册相应BeanDefinition

到这里我们就已经分析完了Aop在spring的嵌入了

总结一下:

1.spring 在启动的时候会通过bean工厂的后置处理器去扫描配置的包下的所有类,并且判断它是不是配置类的候选者(@Component,@Import,@Configurable等,前期文章有说明),把配置类候选者封装成ConfigurationClass,而ConfigurationClass里面有一个importBeanDefinitionRegistrars属性,封装的是循环扫描配置类候选者上面的注解看是否存在@Import,如果存在就把@Import导入的类作为key,注解信息作为Value加入到importBeanDefinitionRegistrars里面,后面在通过封装的ConfigurationClass进行注册BeanDefinition的时候,会拿出importBeanDefinitionRegistrars进行注册BeanDefinition。aop的BeanPostProcessor就是在AspectJAutoProxyRegistrar.registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)注册进去的。

2.上面注册了AbstractAutoProxyCreator的BeanPostProcessor,然后在初始化后会调用

postProcessAfterInitialization(@Nullable Object bean, String beanName) 

通过该方法生成一个Aop代理对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring AOPSpring框架中的一个重要模块,它提供了一种面向切面编程的方式,可以让开发者将一些通用的、横切的关注点(如事务、安全、缓存等)从业务逻辑中剥离出来,使得业务逻辑更加清晰简洁,代码复用更加方便。 Spring AOP的实现原理主要基于Java动态代理和CGLIB动态代理两种方式,其中Java动态代理主要用于接口代理,而CGLIB动态代理则主要用于类代理。Spring AOP中的核心概念是切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)和织入(Weaving)。 在Spring AOP中,切面是一个横向的关注点,它跨越多个对象和方法,通常包含一些通用的功能,如日志记录、安全控制等。连接点则是程序中可以被切面拦截的特定点,如方法调用、异常抛出等。通知是切面在连接点执行前后所执行的动作,包括前置通知(Before)、后置通知(After)、异常通知(AfterThrowing)、返回通知(AfterReturning)和环绕通知(Around)。切点则是用来匹配连接点的规则,它可以指定哪些连接点会被切面拦截。织入则是将切面应用到目标对象中的过程,它可以在编译时、类加载时、运行时等不同的阶段进行。 Spring AOP源码解析涉及到很多细节,包括代理的生成、通知的执行、切点的匹配等,需要深入了解Spring框架的内部实现和Java的反射机制。对于初学者而言,可以先从Spring AOP的基本概念和用法入手,了解其实现原理的同时,也可以通过调试和查看源码来加深理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值