AOP中的几个概念
Advisor 和 Advice
Advice,我们通常都会把他翻译为通知,其实很不好理解,其实他还有另外一个意思,就是“建议”,我觉得把Advice理解为“建议”会更好。
比如,我们已经完成了一个功能,这时客户跟我们说,我建议在这个功能之前可以再增加一些逻辑,再之后再增加一些逻辑。
在Spring中,Advice分为:
- 前置Advice:MethodBeforeAdvice
- 后置Advice:AfterReturningAdvice
- 环绕Advice:MethodInterceptor
- 异常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对比
动态代理 | cglib | jdk |
---|---|---|
是否提供子类代理 | 是 | 否 |
是否提供接口代理 | 是 | 是 |
区别 | 必须依赖于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代理对象。