SpringAOP模块初始化过程

SpringAOP模块初始化过程


        SpringAOP模块的初始化过程可以分为如下几个步骤:

1,读取配置,生成Advisor、PointCut等信息。
        跟SpringAOP的相关标签比较多,我们可以选择任意一种方式声明AOP。如下就使用了三种不同的方式:
	<aop:config>
		<!--切入点,controlller -->
		<aop:pointcut id="pointcut_test"	  expression="execution(* com.test.controller..*index(..))" />
		<!--在该切入点使用自定义拦截器 ,按照先后顺序执行 -->
		<aop:advisor pointcut-ref="pointcut_test" advice-ref="methodInvokeInterceptor" />


		<aop:aspect ref="aspectInterceptor">
			<aop:around method="around" pointcut="execution(* com.test.controller..*index(..))"/>
		</aop:aspect>
	</aop:config>
	<!-- 自动扫描使用了aspectj注解的类 -->
	<aop:aspectj-autoproxy/>
      
2,在容器创建bean的过程中进行拦截,使得可以进行“偷梁换柱”替换原来的bean

    IoC容器在创建bean的时候会调用各种后置处理器,AOP就是利用这些后置处理器在创建bean的过程中做手脚。声明了步骤1中的配置之后,spring会向容器注册AbstractAutoProxyCreator的一些子类。而AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,其中有两个方法实现了AOP的逻辑。下面是AbstractAutoProxyCreator的两个方法:
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!this.targetSourcedBeans.contains(cacheKey)) {
			if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.nonAdvisedBeans.add(cacheKey);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			this.targetSourcedBeans.add(beanName);
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

	public Object postProcessAfterInitialization(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;
	}

3,生成代理返回给容器

     不管上面的哪个方法进行了拦截,都需要调用下面创建代理的方法:
	protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

		ProxyFactory proxyFactory = new ProxyFactory();
		// Copy our properties (proxyTargetClass etc) inherited from ProxyConfig.
		proxyFactory.copyFrom(this);

		if (!shouldProxyTargetClass(beanClass, beanName)) {
			// Must allow for introductions; can't just set interfaces to
			// the target's interfaces only.
			Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
			for (Class<?> targetInterface : targetInterfaces) {
				proxyFactory.addInterface(targetInterface);
			}
		}

		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			proxyFactory.addAdvisor(advisor);
		}

		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(this.proxyClassLoader);
	}

     这里将所有创建代理所需的信息都放入proxyFactory中,然后交给proxyFactory来创建代理。如下:
	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}
     
     而proxyFactory首先创建aopProxy,创建的逻辑在它的父类ProxyCreatorSupport中
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

      ProxyCreatorSupport所使用的aopProxyFactory为DefaultAopProxyFactory,它的createAopProxy方法如下:
	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()) {
				return new JdkDynamicAopProxy(config);
			}
			if (!cglibAvailable) {
				throw new AopConfigException(
						"Cannot proxy target class because CGLIB2 is not available. " +
						"Add CGLIB to the class path or specify proxy interfaces.");
			}
			return CglibProxyFactory.createCglibProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

    这个方法决定了使用cglib还是JDK生成代理, 如果目标类实现了一个或多个接口则利用JDK生成代理。和cglib不同,JDK生成代理不是目标类的子类,若还按目标类型接收则会报错。如果Controller实现了接口并且做了AOP拦截,则AbstractHandlerMethodMapping在扫描HandlerMethod的时候会跳过生成的Controller代理对象

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值