AOP的原理实现和Mybatis整合进Spring中的原理实现一模一样,下面来具体分析一下。在看这篇之前,建议先看下上一篇。
Spring源码系列(八)——Mybatis是如何整合进Spring源码分析
https://blog.csdn.net/zxd1435513775/article/details/121180974
配置类,开启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(); }
对于Import
的处理过程,可以看一下源码分析第四篇,包扫描中处理@Import
注解部分。
Spring源码系列(四)——ConfigurationClassPostProcessor功能解析
https://blog.csdn.net/zxd1435513775/article/details/120935494
@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; }
关于@Import
注解导入ImportBeanDefinitionRegistrar
实现类的介绍可以看一下Spring源码系列(八),
AOP
的原理和Mybatis
的原理一样,都是通过实现ImportBeanDefinitionRegistrar
接口,Mybatis
的实现类是MapperScannerRegistrar
,而AOP
的实现类是AspectJAutoProxyRegistrar
。
// Mybatis
class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar
// AOP
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
在parser.parse(candidates);
这行代码里完成了对@Import
注解的导入工作,并对实现ImportBeanDefinitionRegistrar
接口的类完成了实例化,并把已经创建好的实列放到了ConfigurationClass
类的属性importBeanDefinitionRegistrars
中,可以看下面断点图。
this.reader.loadBeanDefinitions()
这个方法中完成了对ImportBeanDefinitionRegistrar
接口方法的调用。
下面就来看一下AspectJAutoProxyRegistrar
类中实现ImportBeanDefinitionRegistrar
接口的方法了。AOP
的入口就在这里!!!!
来看一下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; }
再观察一下internalAutoProxyCreator
,它的实现类是org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
经过refresh()
方法中的registerBeanPostProcessors()
方法,BeanPostProcessor
就已经实例化了,并且添加到了beanFactory
工厂中的beanPostProcessors
属性中。
我们要来看一下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
,然后再适当的时机进行方法的调用。
两篇文章可以对比着看。