1、首先配置类里面需要加入注解EnableAspectJAutoProxy,后面的(proxyTargetClass = true)涉及到动态代理的类型后面会解释
Configuration和ComponentScan以及Component注解这边就不赘述了;
package com.aop; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.ImportResource; import org.springframework.stereotype.Component; @Configuration @Component("app") @ComponentScan("com.aop") @EnableAspectJAutoProxy//(proxyTargetClass = true) public class AopConfig { }
2、我们进入到EnableAspectJAutoProxy里面可以看出这个类里面通过@Import的形式注入了一个类:AspectJAutoProxyRegistrar;
@Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy {
3、进入到这个类发现他实现了我们大名鼎鼎的ImportBeanDefinitionRegistrar接口,熟悉Spring代码的同学都知道;Spring初始化期间,会调用实现了ImportBeanDefinitionRegistrar的类里面的registerBeanDefinitions方法,所以我们看这个方法:registerAspectJAnnotationAutoProxyCreatorIfNecessary
package org.springframework.context.annotation; import org.springframework.aop.config.AopConfigUtils; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata;
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @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); } } } }
4、一直跟踪这个函数我们会发现最终会执行到这个函数里面:registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);会把AnnotationAwareAspectJAutoProxyCreator注册到beanDefinitionMap里面,名称是:org.springframework.aop.config.internalAutoProxyCreator
@Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; } RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
5、到这里我们需要来看Spring实例化的过程了:首先会有一个测试类;annotationConfigApplicationContext.register(AopConfig.class);及其之前的代码就不再解释了,这边就是创建了一个bean工厂(DefaultListableBeanFactory类型的),然后会向工厂里面注册我们的配置类以及6个类;
package com.aop; import com.config.AppConfig; import com.luban.dao.UserDao; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class TestAop { public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(); annotationConfigApplicationContext.register(AopConfig.class); annotationConfigApplicationContext.refresh(); AopDao dao = (AopDao) annotationConfigApplicationContext.getBean("aopdao"); dao.test(); } }
6、我们来看annotationConfigApplicationContext.refresh();里面执行的代码逻辑(此处中间的逻辑只简单的说明一下,主要看我们的AOP是如何实现的)
refresh方法里面会执行invokeBeanFactoryPostProcessors(beanFactory);之前的方法都是做了一些初始化,这二个方法里面完成了Bean的扫描并放到了beanDefinitionMap里面;这个方法会在处理完Import的类以后结束;有关于Spring中间的实例化过程会在后面的文章中分享;让我们看AOP的过程;
invokeBeanFactoryPostProcessors(beanFactory);
7、在对象创建完成以后会执行一个方法:这个方法传入的参数是bean的name和实例化以后的对象以及BeanDefinition;在这个方法里面会执行后置处理器的before和after方法,这边会遍历我们环境中的所有的后置处理器;其中有一个后置处理器是我们上面第4步的时候注册进去的;看下面截图:
exposedObject = initializeBean(beanName, exposedObject, mbd);
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } @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; }
当遍历到这个后置处理器的时候,在postProcessAfterInitialization方法里面,会通过wrapIfNecessary方法返回一个对象,进入到这个方法可以看出里面调用了
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
进入到这个方法可以看出里面调用了
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
来看一下createProxy方法:方法里面前面的isProxyTargetClass()就是判断配置类里面的下面的这个注解后面是为true还是false
@EnableAspectJAutoProxy//(proxyTargetClass = true)
看这个方法里面最后面一句:
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); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
下面这边厉害了,请看代码:这边就解释了为社么SpringAOP动态代理有的时候用的是JDK,有的时候用的是CGLIB
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { 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."); } //如果对象所属的类是接口 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { //采用的是JDK动态代理 return new JdkDynamicAopProxy(config); } //采用的是CGLIB代理 return new ObjenesisCglibAopProxy(config); } else { //采用的是JDK动态代理 return new JdkDynamicAopProxy(config); } }