zoukankan      html  css  js  c++  java
  • spring-beanFactory四

    前面简单介绍了beanFactory提供的ioc,我们都知道spring使用jdk的动态代理实现了aop,这篇就来看看spring中的aop到底是怎么回事。

    前面有提到,在beanFactory中,getBean会走到AbstractAutowireCapableBeanFactory中的doCreateBean,doCreateBean有如下代码段,populateBean主要是xml注入,initializeBean是初始化,产生aop的逻辑就在initializeBean中。

     1 //doCreateBean的主要逻辑
     2 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
     3     throws BeanCreationException {
     4     //使用工厂方法、构造器注入、简单实例化等策略实例化bean(不是策略模式,只是通过bean definition来决定使用哪种策略,类似switch)
     5     //BeanWrapper是bean的包装类,beanWrapper提供了便捷的方法去更新bean的字段、访问bean的方法,用于注入
     6     BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);//离我们很近
     7     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
     8     //MergedBeanDefinitionPostProcessor的void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
     9     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
    10     // Initialize the bean instance.
    11     //exposedObject即暴露的bean、原生的bean
    12     Object exposedObject = bean;
    13     //先执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,
    14     //再执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,最后再进行xml注入。
    15     //所谓populateBean就是根据该bean在xml的配置信息来填充bean,这些信息已经被解析为BeanDefinition。
    16     populateBean(beanName, mbd, instanceWrapper);
    17     //什么情况下bean==null?
    18     if (exposedObject != null) {
    19         //初始化bean
    20         //invokeAwareMethods(回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的相关方法)、
    21         //applyBeanPostProcessorsBeforeInitialization(回调BeanPostProcessor的postProcessBeforeInitialization方法)、
    22         //invokeInitMethods(回调InitializingBean的afterPropertiesSet,以及init-method)、
    23         //applyBeanPostProcessorsAfterInitialization(回调BeanPostProcessor的postProcessAfterInitialization方法)
    24         exposedObject = initializeBean(beanName, exposedObject, mbd);//离我们很近
    25     }
    26     // Register bean as disposable.
    27     registerDisposableBeanIfNecessary(beanName, bean, mbd);
    28 }
    View Code

    beanFactory就如同它的名字一样,只适合ID,测试AOP这里使用ClassPathXmlApplicationContext。

    FeatureBeanFactoryApplicationContext

    Bean instantiation/wiring

    Yes

    Yes

    Automatic BeanPostProcessor registration

    No

    Yes

    Automatic BeanFactoryPostProcessor registration

    No

    Yes

    Convenient MessageSource access (for i18n)

    No

    Yes

    ApplicationEvent publication

    No

    Yes

    1 populateBean(beanName, mbd, instanceWrapper);
    2 if (exposedObject != null) {
    3     exposedObject = initializeBean(beanName, exposedObject, mbd);
    4 }

    initializeBean会调用applyBeanPostProcessorsAfterInitialization

     1 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
     2         throws BeansException {
     3 
     4     Object result = existingBean;
     5     for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
     6         result = beanProcessor.postProcessAfterInitialization(result, beanName);
     7         if (result == null) {
     8             return result;
     9         }
    10     }
    11     return result;
    12 }

    我们这里只关注和AOP相关的BeanPostProcessor,即org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator,InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization调用的是AbstractAutoProxyCreator的postProcessAfterInitialization,postProcessAfterInitialization又会调用wrapIfNecessary。

     1 //有删减
     2 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
     3     // Create proxy if we have advice.
     4     //得到所有候选Advisor,对Advisors和bean的方法双层遍历匹配,最终得到一个List<Advisor>,即specificInterceptors
     5     Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
     6     if (specificInterceptors != DO_NOT_PROXY) {
     7         this.advisedBeans.put(cacheKey, Boolean.TRUE);
     8         //重点方法
     9         Object proxy = createProxy(
    10                 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    11         this.proxyTypes.put(cacheKey, proxy.getClass());
    12         return proxy;
    13     }
    14 }
     1 //AbstractAutoProxyCreator的createProxy,有删减
     2 protected Object createProxy(
     3         Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
     4 
     5     ProxyFactory proxyFactory = new ProxyFactory();
     6     //Copy configuration from the other config object.
     7     proxyFactory.copyFrom(this);
     8 
     9     Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    10     for (Advisor advisor : advisors) {
    11         proxyFactory.addAdvisor(advisor);
    12     }
    13     //通过targetSource可以得到动态代理的target
    14     proxyFactory.setTargetSource(targetSource);
    15     //getProxy调用了createAopProxy().getProxy(classLoader),proxyFactory.createAopProxy()创建的是JdkDynamicAopProxy
    16     return proxyFactory.getProxy(getProxyClassLoader());
    17 }
    1 public Object getProxy(ClassLoader classLoader) {
    2     Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
    3     findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    4     //jdk的动态代理,因为getProxy的调用者为JdkDynamicAopProxy,所以这里的InvocationHandler就为JdkDynamicAopProxy,最终注册的也是代理bean,target被雪藏
    5     return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    6 }
     1 //JdkDynamicAopProxy的invoke方法,有删减
     2 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     3     MethodInvocation invocation;
     4     Object oldProxy = null;
     5     boolean setProxyContext = false;
     6 
     7     TargetSource targetSource = this.advised.targetSource;
     8     Class<?> targetClass = null;
     9     Object target = null;
    10 
    11     Object retVal;
    12 
    13     // May be null. Get as late as possible to minimize the time we "own" the target,
    14     // in case it comes from a pool.
    15     target = targetSource.getTarget();
    16     if (target != null) {
    17         targetClass = target.getClass();
    18     }
    19 
    20     // Get the interception chain for this method.
    21     //组装拦截链
    22     List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    23 
    24     // Check whether we have any advice. If we don't, we can fallback on direct
    25     // reflective invocation of the target, and avoid creating a MethodInvocation.
    26     if (chain.isEmpty()) {
    27         // We can skip creating a MethodInvocation: just invoke the target directly
    28         // Note that the final invoker must be an InvokerInterceptor so we know it does
    29         // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
    30         Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    31         //通过反射直接调用target的方法
    32         retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    33     }
    34     else {
    35         // We need to create a method invocation...
    36         invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    37         // Proceed to the joinpoint through the interceptor chain.
    38         //走拦截链
    39         retVal = invocation.proceed();
    40     }
    41     //return this时,返回proxy,而不是target
    42     // Massage return value if necessary.
    43     Class<?> returnType = method.getReturnType();
    44     if (retVal != null && retVal == target &&
    45             returnType != Object.class && returnType.isInstance(proxy) &&
    46             !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
    47         // Special case: it returned "this" and the return type of the method
    48         // is type-compatible. Note that we can't help if the target sets
    49         // a reference to itself in another returned object.
    50         retVal = proxy;
    51     }
    52 
    53     return retVal;
    54 
    55 }

    以@Transaction为例来说,XmlBeanFactory在解析xml配置文件时会有专门的NamespaceHandler处理<tx:annotation-driven/>,该NamespaceHandler即TxNamespaceHandler。TxNamespaceHandler会spring注册一个advice,该advice大致会是一个around类型,起到了事务的作用(catch中rollback)。在初始化bean时会遍历bean的方法,检查是否有@Transaction,如果有就对该bean进行动态代理,动态代理中会存该bean的method到adviceChain的映射,执行@Transactional方法时就会从该映射中得到adviceChain。

  • 相关阅读:
    解决运行vue项目的报错This relative module was not found:
    Iterator 迭代器
    Strategy 策略模式
    Observer 观察者
    工厂模式总结(简单工厂,工厂方法,抽象工厂)
    Abstract Factory 抽象工厂
    Factroy 简单工厂
    Singleton 多线程
    Singleton 单例模式
    设计模式总结
  • 原文地址:https://www.cnblogs.com/holoyong/p/7367741.html
Copyright © 2011-2022 走看看