zoukankan      html  css  js  c++  java
  • Spring AOP源码分析

    https://cloud.tencent.com/developer/article/1512235
    https://www.cnblogs.com/wangshen31/p/9379197.html
    https://blog.csdn.net/woshilijiuyi/article/details/83934407

    总结

    1. spring容器在初始化时,进行applyBeanPostProcessorsAfterInitialization处理
    2. 调用AbstractAutoProxyCreator的postProcessAfterInitialization方法
    3. 当处理满足@Pointcut中条件的Bean时,getAdvicesAndAdvisorsForBean不为null,执行生成Proxy逻辑
    4. 当想调用被代理类中方法时,Proxy类进行代理;实现横切面逻辑

    生成代理类

    如Pointcut在controller中时

    @Pointcut("execution(* com.java.study.controller.*.*(..))")
    public void logPointcut() { }
    

    则在预实例化时,在AbstractAutowireCapableBeanFactory中doCreateBean方法对Bean进行实例化、属性注入和初始化

    Object exposedObject = bean;
    try {
    	populateBean(beanName, mbd, instanceWrapper);
    	exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    

    初始化时,调用applyBeanPostProcessorsAfterInitialization方法

    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        ......
    	if (mbd == null || !mbd.isSynthetic()) {
    		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    	}
    
    	return wrappedBean;
    }
    

    其中processor为AnnotationAwareAspectJAutoProxyCreator时

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    		throws BeansException {
    
    	Object result = existingBean;
    	for (BeanPostProcessor processor : getBeanPostProcessors()) {
    	    //AnnotationAwareAspectJAutoProxyCreator
    		Object current = processor.postProcessAfterInitialization(result, beanName);
    		if (current == null) {
    			return result;
    		}
    		result = current;
    	}
    	return result;
    }
    

    因AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator ,AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator,调父类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;
    }
    

    调用AbstractAutoProxyCreator#wrapIfNecessary()

    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;
    }
    

    最后返回specificInterceptors不为null,开始创建Proxy。调用AbstractAutoProxyCreator#createProxy(),set
    advisors和targetSource

    	protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    			@Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
    		ProxyFactory proxyFactory = new ProxyFactory();
    		proxyFactory.copyFrom(this);
            ......
            Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    		proxyFactory.addAdvisors(advisors);
            proxyFactory.setTargetSource(targetSource);
    		customizeProxyFactory(proxyFactory);
            ......
    		return proxyFactory.getProxy(getProxyClassLoader());
    	}
    

    ProxyCreatorSupport#createAopProxy() --> DefaultAopProxyFactory#createAopProxy(),判断走JDK动态代理还是CGLIB代理,此时由于代理是类,返回new ObjenesisCglibAopProxy(config)

    @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)) {
    			return new JdkDynamicAopProxy(config);
    		}
    		return new ObjenesisCglibAopProxy(config);
    	}
    	else {
    		return new JdkDynamicAopProxy(config);
    	}
    }
    

    走CglibAopProxy#getProxy()

    	@Override
    	public Object getProxy(@Nullable ClassLoader classLoader) {
    		if (logger.isTraceEnabled()) {
    			logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
    		}
    
    		try {
    			Class<?> rootClass = this.advised.getTargetClass();
    			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
    
    			Class<?> proxySuperClass = rootClass;
    			......
    
    			// Validate the class, writing log messages as necessary.
    			validateClassIfNecessary(proxySuperClass, classLoader);
    
    			// Configure CGLIB Enhancer...
    			Enhancer enhancer = createEnhancer();
    			if (classLoader != null) {
    				enhancer.setClassLoader(classLoader);
    				if (classLoader instanceof SmartClassLoader &&
    						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
    					enhancer.setUseCache(false);
    				}
    			}
    			enhancer.setSuperclass(proxySuperClass);
    			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
    			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
    			enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
    
    			Callback[] callbacks = getCallbacks(rootClass);
    			Class<?>[] types = new Class<?>[callbacks.length];
    			for (int x = 0; x < types.length; x++) {
    				types[x] = callbacks[x].getClass();
    			}
    			// fixedInterceptorMap only populated at this point, after getCallbacks call above
    			enhancer.setCallbackFilter(new ProxyCallbackFilter(
    					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
    			enhancer.setCallbackTypes(types);
    
    			// Generate the proxy class and create a proxy instance.
    			return createProxyClassAndInstance(enhancer, callbacks);
    		}
    		......
    	}
    
    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    	enhancer.setInterceptDuringConstruction(false);
    	enhancer.setCallbacks(callbacks);
    	return (this.constructorArgs != null && this.constructorArgTypes != null ?
    			enhancer.create(this.constructorArgTypes, this.constructorArgs) :
    			enhancer.create());
    }
    
    生成Advisor过程

    调用链:

    AbstractApplicationContext#onRefresh() --> ServletWebServerApplicationContext#onRefresh() -->
    ServletWebServerApplicationContext#createWebServer() -->ServletWebServerApplicationContext#getWebServerFactory -->DefaultListableBeanFactory#getBeanNamesForType() -->DefaultListableBeanFactory#doGetBeanNamesForType() -->AbstractBeanFactory#isTypeMatch() -->AbstractAutowireCapableBeanFactory#getTypeForFactoryBean() -->AbstractAutowireCapableBeanFactory#getSingletonFactoryBeanForTypeCheck() -->AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation() -->AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation()-->AbstractAutoProxyCreator#postProcessBeforeInstantiation() -->AspectJAwareAdvisorAutoProxyCreator#shouldSkip()-->AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors() --> BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()

    1. cachedAdvisorBeanNames赋值过程

    在AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()时,调用super.findCandidateAdvisors();

    @Override
    protected List<Advisor> findCandidateAdvisors() {
    	// Add all the Spring advisors found according to superclass rules.
    	List<Advisor> advisors = super.findCandidateAdvisors();
    	// Build Advisors for all AspectJ aspects in the bean factory.
    	if (this.aspectJAdvisorsBuilder != null) {
    		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    	}
    	return advisors;
    }
    

    然后调用BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans()时,this.cachedAdvisorBeanNames = advisorNames;指向String数组,不再为null

    public List<Advisor> findAdvisorBeans() {
    	// Determine list of advisor bean names, if not cached already.
    	String[] advisorNames = this.cachedAdvisorBeanNames;
    	if (advisorNames == null) {
    		// Do not initialize FactoryBeans here: We need to leave all regular beans
    		// uninitialized to let the auto-proxy creator apply to them!
    		advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
    				this.beanFactory, Advisor.class, true, false);
    		this.cachedAdvisorBeanNames = advisorNames;
    	}
    }
    
    1. 生成List过程

    buildAspectJAdvisors方法先获取所有beanNames

    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
    

    当执行到有@Aspect注解的AopLog时,isAspect为true,进行处理

    //true
    if (this.advisorFactory.isAspect(beanType)) {
        ......
    }
    
    @Override
    public boolean isAspect(Class<?> clazz) {
    	return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
    }
    

    获取切面中所有advice

    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
    
    获取List过程

    调用getAdvicesAndAdvisorsForBean()

    @Override
    @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(
    		Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    
    	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    	if (advisors.isEmpty()) {
    		return DO_NOT_PROXY;
    	}
    	return advisors.toArray();
    }
    

    调用findEligibleAdvisors()

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    	List<Advisor> candidateAdvisors = findCandidateAdvisors();
    	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    	extendAdvisors(eligibleAdvisors);
    	if (!eligibleAdvisors.isEmpty()) {
    		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    	}
    	return eligibleAdvisors;
    }
    

    由于BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans()中cachedAdvisorBeanNames不为null,结果返回new ArrayList<>()

    @Override
    protected List<Advisor> findCandidateAdvisors() {
    	// Add all the Spring advisors found according to superclass rules.
    	List<Advisor> advisors = super.findCandidateAdvisors();
    	// Build Advisors for all AspectJ aspects in the bean factory.
    	if (this.aspectJAdvisorsBuilder != null) {
    		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    	}
    	return advisors;
    }
    

    执行BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors(),直接在缓存中取出advisor

    public List<Advisor> buildAspectJAdvisors() {
    	List<String> aspectNames = this.aspectBeanNames;
        ......
    	List<Advisor> advisors = new ArrayList<>();
    	for (String aspectName : aspectNames) {
    		List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
    		if (cachedAdvisors != null) {
    		    //执行
    			advisors.addAll(cachedAdvisors);
    		}
    		else {
    			MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
    			advisors.addAll(this.advisorFactory.getAdvisors(factory));
    		}
    	}
    	return advisors;
    }
    

    TODO

    SpringMVC源码

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出。
  • 相关阅读:
    FCKeditor 2.3 在ASP.NET中的设置和使用
    如何去掉重复记录的Sql语句写法
    asp.net如何去掉HTML标记
    Asp.net中如何删除cookie?
    怎样得到select所有option里的值
    HttpModule是如何工作的
    Asp.net2.0下的表单验证Cookieless属性
    FreeTextBox实现机制
    ajax实现动态从数据库模糊查询显示到下拉框中(ajax方法返回Dataset的例子)
    新浪博客自动发表程序,请勿用于非法用途
  • 原文地址:https://www.cnblogs.com/caozibiao/p/13976408.html
Copyright © 2011-2022 走看看