看这一遍默认你对spring aop使用非常了解,对动态代理也有一定的了解,如果确实不是很了解请看下面的几篇使用相关的文档
spring 学习之四(spring的注入方式(xml和annotation))
spring学习之五(spring aop编程)
aop其实就是对我们目前的方法进行增强,根据我们以前的知识储备知道 AnnotationAwareAspectJAutoProxyCreator这个类是aop实现的一个比较核心的一个类,这个类也是一个BeanPostProcessor类,这样根据我们对ioc容器初始化就比较容易理解了,
1.在beanBactory初始化过程中将BeanPoster注册到BeanDefinitionMap中
2. Bean在初始化时进行对bean增强, 也就是在init方法前后进行操作
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { /** * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed * to standard Java interface-based proxies. The default is {@code false}. */ boolean proxyTargetClass() default false; /** * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal} * for retrieval via the {@link org.springframework.aop.framework.AopContext} class. * Off by default, i.e. no guarantees that {@code AopContext} access will work. * @since 4.3.1 */ boolean exposeProxy() default false; }
@Import(AspectJAutoProxyRegistrar.class) 这个我们知道导入了一个注册类AspectJAutoProxyRegistrar组件
@Import 注解源码参考
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); } } } }
这个方法就是处理我们在使用@EnableAspectJAutoProxy 中的两个属性( exposeProxy proxyTargetClass),默认两个都为false 先不深入了解这个了
@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
此时将AnnotationAwareAspectJAutoProxyCreator 注册到beandefinitionmap中
@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; }
IOC容器中注入了一个internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator的beandefintion,到此可以得出结论,@EnableAspectJAutoProxy给容器中注册一个AnnotationAwareAspectJAutoProxyCreator。
我们从下图可以知道继承接口BeanFactoryAware 和BeanPostProcessor接口因此我们可以知道在bean初始化时回出发
在此需要关注两点内容:
1)关注后置处理器SmartInstantiationAwareBeanPostProcessor(在bean初始化完成前后做事情)
2)关注自动装配BeanFactory。
通过代码查看,发现父类AbstractAutoProxyCreator中有后置处理器的内容;AbstactAdvisorAutoProxyCreator类中重写了其父类AbstractAutoProxyCreator中setBeanFactory()方法,在AnnotationAwareAspectJAutoProxyCreator类中initBeanFactory()方法完成了自动装配BeanFactory。分别在这两处关注点打断点来查看其流程:
我们知道AbstactAdvisorAutoProxyCreator 初始化时的一个大致过程如下:
setBeanFactory方法和BeanPostProcessorsBeforeInitialization BeanPostProcessorsAfterInitialization 顺序如下图
源码逻辑:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
该方法比较简单:
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory @Override public void setBeanFactory(BeanFactory beanFactory) { super.setBeanFactory(beanFactory); if (!(beanFactory instanceof ConfigurableListableBeanFactory)) { throw new IllegalArgumentException( "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory); } initBeanFactory((ConfigurableListableBeanFactory) beanFactory); } protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory); } 子类重写了initBeanFactory方法 @Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.initBeanFactory(beanFactory); if (this.aspectJAdvisorFactory == null) { this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory); } this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory); }
我看的5.3.x版本的spring 开始没重写 这个before方法
实例化
此时看beanpostProcessor 工作原理
1)、传入配置类,创建ioc容器 2)、注册配置类,调用refresh()刷新容器; 3)、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建; 1)、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor 2)、给容器中加别的BeanPostProcessor 3)、优先注册实现了PriorityOrdered接口的BeanPostProcessor; 4)、再给容器中注册实现了Ordered接口的BeanPostProcessor; 5)、注册没实现优先级接口的BeanPostProcessor; 6)、注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中; 创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】 1)、创建Bean的实例 2)、populateBean;给bean的各种属性赋值 3)、initializeBean:初始化bean; 1)、invokeAwareMethods():处理Aware接口的方法回调 2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization() 3)、invokeInitMethods();执行自定义的初始化方法 4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization(); 4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--》aspectJAdvisorsBuilder 7)、把BeanPostProcessor注册到BeanFactory中; beanFactory.addBeanPostProcessor(postProcessor); =======以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程========
从上面我分析的逻辑和前置知识非常清楚,当我们自己编写的类填写@EnableAspectJAutoProxy或者通过其他方式开启aop都是在docreateBean方法中进行增强:
我们在这个方法入口打断点 使用断点的方式进行跟踪分析:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
exposedObject = initializeBean(beanName, exposedObject, mbd);
这个方法上面我都分析了aware相关的方法, before init after方法,由于 自己的类非aware ,因此不会执行, before没有重写, 因此不重要下面直接after方法
进来的时候实体对象不是代理对象,我们继续往下看从哪里开始处理成的代理对象的
从上面分析我们可以知道Spring入住了AnnotationAwareAspectJAutoProxyCreator 一个BeanPostProcessor类,又知道改类没有重写before方法,因此after方法才是我们的重点:
重写 beanpostprocessor的after方法
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization @Override 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; }
这个地方是二级缓存中存在,删除进行创建对象,ps:二级缓存中存放的是只进行实例化,没有进行初始化的对象
postProcessAfterInitialization方法会对切面进行一次包装的处理。
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; } // Create proxy if we have advice. //获取我们配置的切面 根据切面进行动态代理 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; }
下面进行创建代理对象
第一步:创建代理对象的ProxyFactory 工厂
第二步:使用工厂模式创建代理对象
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()) { // Explicit handling of JDK proxy targets (for introduction advice scenarios) if (Proxy.isProxyClass(beanClass)) { // Must allow for introductions; can't just set interfaces to the proxy's interfaces only. for (Class> ifc : beanClass.getInterfaces()) { proxyFactory.addInterface(ifc); } } } else { // No proxyTargetClass flag enforced, let's apply our default checks... 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); } // Use original ClassLoader if bean class not locally loaded in overriding class loader ClassLoader classLoader = getProxyClassLoader(); if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) { classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader(); } return proxyFactory.getProxy(classLoader); }
proxyFactory 工厂拿到了目标对象和定义的切点信息 封装放到这个对象Advisor
我们细看创建代理对象的过程,发现在创建之前首先会根据切入点表达式对增强器进行一一匹配,最终拿到所有的增强器。
创建代理对象:
我们又知道spring创建代理对象有两种方式:jdk动态代理和cglib动态代理
public Object getProxy(@Nullable ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
spring 是通过AdvisedSupport 类获取当前用户配置的方式,spring默认使用cglib动态代理
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (!NativeDetector.inNativeImage() && (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."); } //如果目标类是接口或者代理类 使用jdk代理 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
真正获取代理对象的地方cglib代理方式
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader) //根据目标对象获取一堆拦截器 //这就是给代理对象增强的核心代码 Callback[] callbacks = getCallbacks(rootClass);
Callback[] callbacks = getCallbacks(rootClass);
这个地方先混个眼熟,到调用方法时会使用这些拦截器
上面我们就把代理类生产了并且放到容器beanmap里面了
其中生产的过程自己断点看看吧 这个地方我们只看了一个cglib方式生产,底层使用的asm 比较复杂,这里就不再赘述.
获取该对象看看代理对象中包含很多拦截器因此先进拦截器中
这个时候拦截器就起作用了直接进入下面的方法
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept //获取可以应用到此方法上的Interceptor列表 List
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
反射机制 掉用proceed 走父类的
ReflectiveMethodInvocation
通过反射就可以在执行代码的前后进行增强了
这个地方自己不是很熟悉的可以自己看看 反射和动态代理相关的知识