Spring中的AOP动态代理源码详解
作者:止步前行
一、Spring启动流程再分析
配置类,开启 AOP 的注解 @EnableAspectJAutoProxy
@Configuration @ComponentScan("com.scorpios") @EnableAspectJAutoProxy public class AppConfig { }
切面类
@Aspect @Component public class AspectJScorpios { @Pointcut("execution(* com.scorpios.service..*.*(..))") public void pointCut(){ } @Before("pointCut()") public void before(){ System.out.println(" proxy before ... "); } }
启动类
public static void main( String[] args ) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.register(AppConfig.class); ac.refresh(); XService xService = (XService) ac.getBean("XService"); xService.print(); }
1. 处理Import过程
对于 Import 的处理过程,可以看一下源码分析第四篇,包扫描中处理 @Import 注解部分。
@EnableAspectJAutoProxy 注解源码,使用 @Import 注解,向 Spring 容器中导入 AspectJAutoProxyRegistrar 类,而 AspectJAutoProxyRegistrar 类实现 ImportBeanDefinitionRegistrar 接口。
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false; }
AOP 的原理和 Mybatis 的原理一样,都是通过实现 ImportBeanDefinitionRegistrar 接口, Mybatis 的实现类是 MapperScannerRegistrar ,而 AOP 的实现类是 AspectJAutoProxyRegistrar 。
// Mybatis
class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar
// AOP
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
2. 执行Import导入类
在 parser.parse(candidates); 这行代码里完成了对 @Import 注解的导入工作,并对实现 ImportBeanDefinitionRegistrar 接口的类完成了实例化,并把已经创建好的实列放到了 ConfigurationClass 类的属性 importBeanDefinitionRegistrars 中,可以看下面断点图。
this.reader.loadBeanDefinitions() 这个方法中完成了对 ImportBeanDefinitionRegistrar 接口方法的调用。
下面就来看一下 AspectJAutoProxyRegistrar 类中实现 ImportBeanDefinitionRegistrar 接口的方法了。
AOP 的入口就在这里!!!!
二、AOP源码分析
1. AspectJAutoProxyRegistrar类
来看一下 AspectJAutoProxyRegistrar 类中实现 ImportBeanDefinitionRegistrar 接口方法。
该方法的作用就是往 Spring 容器中添加一个 BeanDefinition , beanName 为 org.springframework.aop.config.internalAutoProxyCreator 。
beanClass 为 AnnotationAwareAspectJAutoProxyCreator.class 。
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); } } } }
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) { return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null); } public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); } private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { 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; } // 此处的的beanClass为AnnotationAwareAspectJAutoProxyCreator.class RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 往beanDefinitionMap中注册一个beanName为org.springframework.aop.config.internalAutoProxyCreator的BeanDefinition registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
2. internalAutoProxyCreator类
再观察一下 internalAutoProxyCreator
,它的实现类是 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
经过 refresh() 方法中的 registerBeanPostProcessors() 方法, BeanPostProcessor 就已经实例化了,并且添加到了 beanFactory 工厂中的 beanPostProcessors 属性中。
3. BeanPostProcessor方法执行
我们要来看一下 BeanPostProcessor 的执行时机,在 populateBean() 属性赋值之后的 initializeBean() 方法中,进行了 Bean后置处理器 方法的调用。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { // 权限检查 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 执行setBeanName/setBeanFactory赋值 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessor接口中的postProcessBeforeInitialization()方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 执行自定义的init-method方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { // 抛异常代码略 } if (mbd == null || !mbd.isSynthetic()) { // 调用BeanPostProcessor接口中的postProcessAfterInitialization()方法 // AOP代理就在AnnotationAwareAspectJAutoProxyCreator类此方法中 // AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现了此方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
上面这个 AnnotationAwareAspectJAutoProxyCreator 类中的 postProcessAfterInitialization() 方法执行过后, XService 实例就变成了 Cglib 代理对象了。
下面来分析下源码:
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; }
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } 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; }
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); } public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { // 这个判断很重要,可以通过配置文件进行配置,来决定采用什么动态代理 if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { // 抛异常略 } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { // 创建JDK动态代理 return new JdkDynamicAopProxy(config); } // 创建Cglib动态代理 return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
三、小结
AOP的原理和Mybatis的原理一样,都是利用了Spring中@Import导入ImportBeanDefinitionRegistrar这个扩展点。
先往容器中添加一个BeanDefinition,然后再适当的时机进行方法的调用。
到此这篇关于Spring中的AOP动态代理源码详解的文章就介绍到这了,更多相关AOP动态代理源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!