• 更加紧密团结在以习近平同志为核心的党中央周围  2019-05-21
  • 马拉维“红旗飘飘”十年间,中国工程印上了当地纸币 2019-05-21
  • 庆祝人民日报创刊70周年系列访谈之颜世贵 2019-05-15
  • 国产新型雷达芯片华睿2号与组网中心同时亮相 2019-05-15
  • VRAR从热转凉 追风上市公司“跌落神坛”追风上市公司“跌落神坛”-手机行情 2019-05-06
  • The GNU General Public License v3.0 2019-05-05
  • 第21届上海国际电影节启幕 设“一带一路电影周” 2019-04-11
  • 广西壮族自治区东兰县“七民一站一阵地工作法”维护群众权益 2019-04-08
  • 苗山脱贫影像志——父母在 不远行 2019-04-08
  • 竹编:缝隙里的乡愁文章中国国家地理网 2019-03-31
  • “几乎是时时在流血、天天有牺牲”,他们的故事你知道吗? 2019-03-31
  • 当前位置:浙江十一选五开奖直播 >  域名 >  正文 > 处世哲学名言

    浙江十一选五开奖直播 www.wmdzr.com   交易 任务 SEO服务 站长团购 联盟

    成神又如何,征服世界又如何?唐欣所需要的是要让蓝姨,夏叔等人过上好曰子,是要让他们无忧无虑,替自己艹劳了十几年,唐欣无法忘却,无法不报答。

    青春期——改变人生的最后机会

    那鬼子军官立即下意识的卧倒在地,随后一阵震天动地的爆炸声在开阔地上轰然响起,爆炸的气浪直接将附件的十来个鬼子兵给撕裂成了碎片,将趴在地上的鬼子军官狠狠的推出去了老远。
    “夏日星,跟我说说外面现在发展成什么样子了?“千手纲手知道自己闭关的日子看似短(再刹那芳华里面渡过了十四个月还短?不过现实里面却是过去了七天的确挺短的。),但忍界这段时间每一天都会发生一些大事的,当然要听听了。

    风起,云涌……无量的天劫之气疯狂的集聚,同时,纪太虚感到五行元气也在不住的向这里涌来。

    我们跟踪一下


      AOP(面向切面编程)在Spring中是被广泛应用的(例如日志,事务,权限等),而它的基本原理便是动态代理。

      我们知道动态代理有两种:基于JDK的动态代理以及基于CGlib动态代理。以下是两种动态代理的实现方式:

     1 //JDK动态代理
     2 public class JDKProxy implements InvocationHandler {
     3  
     4   private Object object;// 被代理人
     5    
     6   //这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理。但是要注意下面的newProxyInstance()中的参数
     7   public Object getInstance(Object object) {
     8     this.object = object;
     9     //与cglib的区别在于这里构建代理对象的时候需要传入被代理对象的接口对象,第二个参数。而cglib不需要被代理对象实现任何接口即可    
    10     return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this);
    11   }
    12  
    13     //代理对象真正调用的方法
    14   @Override
    15   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    16     System.out.println("doSomething---------start");
    17     method.invoke(object, args);
    18     System.out.println("doSomething---------end");
    19     return null;
    20   }
    21  
    22 }
    23 
    24 //CGlib动态代理
    25 public class CglibProxy implements MethodInterceptor {
    26   private Object targetObject;
    27  
    28   // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
    29   public Object getInstance(Object target) {
    30     this.targetObject = target;
    31     Enhancer enhancer = new Enhancer();
    32     enhancer.setSuperclass(target.getClass());
    33     enhancer.setCallback(this);
    34     //注意该处代理的创建过程
    35     Object proxyObj = enhancer.create();
    36     return proxyObj;// 返回代理对象
    37   }
    38  
    39     //代理对象真正调用的方法
    40   @Override
    41   public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    42     Object obj = null;
    43     System.out.println("doSomething---------start");
    44     obj = method.invoke(targetObject, args);
    45     System.out.println("doSomething---------end");
    46     return obj;
    47   }
    48  
    49 }
    View Code

      具体两种动态代理的差异在网上有很多各个方面的比较,在这里我就不再赘述。下面我再说说在Spring?5.0.3.RELEASE中实现AOP的原理(我的github中也有详细的源码注释)。

      在注解版的Spring AOP当中我们会有如下的代码配置,其中@EnableAspectJAutoProxy便是开启AOP支持的关键。

     1 @EnableAspectJAutoProxy //开启基于注解的AOP模式
     2 @Configuration
     3 @ComponentScan(value = {"com.aop"})
     4 public class AnnotationAopConfig {
     5 
     6     @Bean("student")
     7     public Student getStudent() { //把我们普通的Java Bean定义出来交给IOC容器管理
     8         return new Student();
     9     }
    10 
    11     @Bean
    12     public LogAspect getLogAspect() { //定义切面类
    13         return new LogAspect();
    14     }
    15 }

      我们跟踪一下@EnableAspectJAutoProxy的源码来看看它的定义,会发现它利用@Import导入了AspectJAutoProxyRegistrar.class组件:代码块一

      由AspectJAutoProxyRegistrar.Class的定义可知其实现了ImportBeanDefinitionRegistrar接口,所以在IOC容器初始化的时候会调用该类的registerBeanDefinitions方法。通过观察该方法实现,我们可以看到一行关键的代码AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);:代码块二

      这行代码中所需要注册的到底是什么东西呢?我们进一步一探究竟。在持续跟入代码的过程中我们可以找到这么一块代码:return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);:代码块三

      观察源码可以得知,该方法会将AnnotationAwareAspectJAutoProxyCreator类封装为一个RootBeanDefinition然后添加到BeanDefinition的注册类当中以AUTO_PROXY_CREATOR_BEAN_NAME。我们也可以找到关于AUTO_PROXY_CREATOR_BEAN_NAME的定义:代码块四

      我们再分析一下AnnotationAwareAspectJAutoProxyCreator.Class的源码,看看此类到底有何特别之处。观察源码我们可以发现AnnotationAwareAspectJAutoProxyCreator是BeanPostPrcsessor的子类:代码块五

    ?

     1  /**********************代码块一***********************/
     2  
     3  @Target(ElementType.TYPE)
     4  @Retention(RetentionPolicy.RUNTIME)
     5  @Documented
     6  @Import(AspectJAutoProxyRegistrar.class) //导入AspectJAutoProxyRegistrar组件
     7  public @interface EnableAspectJAutoProxy {
     8  /**********************代码块二***********************/
     9  class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    10  
    11      @Override
    12      public void registerBeanDefinitions(
    13              AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    14  
    15          AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //如果需要的话注册AspectJAnnotationAutoProxy
    16  /**********************代码块三***********************/
    17  @Nullable
    18  public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
    19        @Nullable Object source) {
    20  
    21     return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
    22  }
    23  /**********************代码块四***********************/
    24  /**
    25   * The bean name of the internally managed auto-proxy creator.
    26   */
    27  public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
    28  private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
    29        @Nullable Object source) {
    30  
    31     Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    32  
    33     if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
    34        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
    35        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
    36           int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
    37           int requiredPriority = findPriorityForClass(cls);
    38           if (currentPriority < requiredPriority) {
    39              apcDefinition.setBeanClassName(cls.getName());
    40           }
    41        }
    42        return null;
    43     }
    44  
    45     RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    46     beanDefinition.setSource(source);
    47     beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    48     beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    49     registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);//注册
    50     return beanDefinition;
    51  }
    52  /**********************代码块五***********************/
    53 AnnotationAwareAspectJAutoProxyCreator
    54   AnnotationAwareAspectJAutoProxyCreator
    55     extends AspectJAwareAdvisorAutoProxyCreator
    56       extends AbstractAdvisorAutoProxyCreator
    57         extends AbstractAutoProxyCreator
    58           extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
    59             extends ...InstantiationAwareBeanPostProcessor Ordered
    60               extends BeanPostProcessor

    ?

      从以上代码,我们可以知道@EnableAspectJAutoProxy大概做了这么一件事:将AnnotationAwareAspectJAutoProxyCreator.Class以名为“org.springframework.aop.config.internalAutoProxyCreator”的方式完成注册BeanDefinition的操作。

      然后我们再看看这块内容对Spring容器启动过程的影响。

      我们以下面的代码为入口进行分析:代码块一

      我们进入IOC容器初始化过程看看对于进行了切面操作的类来说经历了哪些操作,通过断点我们可以跟踪到此代码处:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);这里是实例化各种BeanPostProcessor,并将其实例存放在BeanFactory当中:代码块二(当中代码我挑出重要的部分。更加详细的Spring源码说明,请关注我的github)。

      注册了BeanPostProcessor的实例,我们看看普通Bean对象的创建。跟踪源码可知:通过finishBeanFactoryInitialization等一系列方法的调用到getBean(beanName);方法之中,在getBean(beanName);后续的调用之中又经过了查询缓存,实例化依赖等一系列操作来到了createBean这个方法当中,我们可以通过代码详细分析其处理。我们可以找到Object beanInstance = doCreateBean(beanName, mbdToUse, args); 获取Bean实例的地方。 再跟进去看它的实现:代码块三

      我们现在观察doCreateBean(beanName, mbdToUse, args); 源码,其中实现了移除缓存、创建实例、初始化实例等一系列操作,其中在exposedObject = initializeBean(beanName, exposedObject, mbd);中变有我们需要的关键信息。:代码块四

      initializeBean(beanName, exposedObject, mbd);这个方法里面有applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);和applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);两个方法的调用。这里面的原理是获取所有的beanPostProcessors遍历调用其postProcessBeforeInitialization和postProcessAfterInitialization方法。这里我就不过多的赘述了。调试代码我们可以发现后续的调用链如下AbstractAutoProxyCreator#postProcessAfterInitialization-->AbstractAutoProxyCreator#wrapIfNecessary。在这里我们就可以判断其是否拥有增强器来创建代理对象,我们可以通过下面代码来观察其逻辑(增强器便是代理对象的各个方法封装起来的对象):代码块五

      进入代理构建入口Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));以下便是通过默认的GClib来进行对象的一个封装。其代理封装的对象如下:代码块六

      1 /**********************代码块一***********************/
      2   @Test
      3     public void test3() {
      4         AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationAopConfig.class); //初始化IOC容器
      5         String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
      6 
      7         Student student = (Student) applicationContext.getBean("student");//从容器中获取对象
      8         student.innerMethod(); //进行方法调用
      9         applicationContext.close();
     10     }
     11 /**********************代码块二***********************/
     12 public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
     13   /**
     14   * IOC:stepA6-1 获取到所有已经定义了的,需要创建实例的所有实现BeanPostProcessor的类
     15   * org.springframework.context.annotation.internalAutowiredAnnotationProcessor
     16   * org.springframework.context.annotation.internalRequiredAnnotationProcessor
     17   * org.springframework.aop.config.internalAutoProxyCreator
     18   */
     19   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
     20   ....
     21   /**
     22   * 分离实现了PriorityOrdered、Ordered和rest接口的BeanPostProcessors
     23   * 按顺序注册BeanPostProcessors
     24   */
     25   List<String> orderedPostProcessorNames = new ArrayList<>();
     26   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
     27   for (String ppName : postProcessorNames) {
     28     if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //如果是PriorityOrdered的子类
     29       ....
     30     }
     31     else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //AOP 匹配internalAutoProxyCreator,添加到orderedPostProcessorNames集合当中
     32       orderedPostProcessorNames.add(ppName);
     33     }
     34     else {
     35       nonOrderedPostProcessorNames.add(ppName);
     36     }
     37   }
     38    // 首先, 注册实现PriorityOrdered接口的BeanPostProcessors
     39   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
     40   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
     41   // Next, register the BeanPostProcessors that implement Ordered.
     42   List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
     43   for (String ppName : orderedPostProcessorNames) {
     44     BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //实例化internalAutoProxyCreator
     45     orderedPostProcessors.add(pp);
     46     if (pp instanceof MergedBeanDefinitionPostProcessor) {
     47       internalPostProcessors.add(pp);//将internalAutoProxyCreator实例放进去
     48     }
     49   }
     50   sortPostProcessors(orderedPostProcessors, beanFactory);
     51   registerBeanPostProcessors(beanFactory, orderedPostProcessors); //将BeanPostProcessor注册到BeanFactory
     52   ....
     53 }
     54 /**********************代码块三***********************/
     55 
     56 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
     57       throws BeanCreationException {
     58   ....
     59 
     60    try {
     61       // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
     62       //IOC:stepA10 给BeanPostProcessor一个机会返回一个代理实例代替Bean实例
     63       Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
     64       if (bean != null) {
     65          return bean;
     66       }
     67    }
     68    catch (Throwable ex) {
     69       throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
     70             "BeanPostProcessor before instantiation of bean failed", ex);
     71    }
     72 
     73    try {
     74       Object beanInstance = doCreateBean(beanName, mbdToUse, args);  //创建Bean实例
     75       if (logger.isDebugEnabled()) {
     76          logger.debug("Finished creating instance of bean "" + beanName + """);
     77       }
     78       return beanInstance;
     79    }
     80    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
     81       ....
     82    }
     83 }
     84 /**********************代码块四***********************/
     85 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
     86       throws BeanCreationException {
     87    // Instantiate the bean.
     88    BeanWrapper instanceWrapper = null;
     89    if (mbd.isSingleton()) { //如果是单例,从factoryBean实例缓存中移除
     90       instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
     91    }
     92    if (instanceWrapper == null) {
     93       instanceWrapper = createBeanInstance(beanName, mbd, args);//创建实例
     94    }
     95   ....
     96    //缓存bean解决循环引用
     97    ....
     98    // Initialize the bean instance.
     99    //初始化bean实例
    100    Object exposedObject = bean;
    101    try {
    102       populateBean(beanName, mbd, instanceWrapper); //为Bean的属性赋值
    103       exposedObject = initializeBean(beanName, exposedObject, mbd); //初始化对象
    104    }
    105   ....
    106    }
    107 /**********************代码块五***********************/
    108 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    109    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    110       return bean;
    111    }
    112    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    113       return bean;
    114    }
    115    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    116       this.advisedBeans.put(cacheKey, Boolean.FALSE);
    117       return bean;
    118    }
    119 
    120    // Create proxy if we have advice.
    121    //如果有增强器的话就创建代理
    122    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    123    if (specificInterceptors != DO_NOT_PROXY) {
    124       this.advisedBeans.put(cacheKey, Boolean.TRUE);
    125       Object proxy = createProxy(
    126             bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));//创建AOP代理对象
    127       this.proxyTypes.put(cacheKey, proxy.getClass());
    128       return proxy;
    129    }
    130 
    131    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    132    return bean;
    133 }
    134 /**********************代码块六***********************/
    135 private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
    136 
    137    private final AdvisedSupport advised;
    138 
    139    public DynamicAdvisedInterceptor(AdvisedSupport advised) {
    140       this.advised = advised;
    141    }
    142 
    143    @Override
    144    @Nullable
    145    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    146       Object oldProxy = null;
    147       boolean setProxyContext = false;
    148       Object target = null;
    149       TargetSource targetSource = this.advised.getTargetSource();
    150       try {
    151          if (this.advised.exposeProxy) {
    152             // Make invocation available if necessary.
    153             oldProxy = AopContext.setCurrentProxy(proxy);
    154             setProxyContext = true;
    155          }
    156          // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
    157          target = targetSource.getTarget();
    158          Class<?> targetClass = (target != null ? target.getClass() : null);
    159          List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);//根据将要执行的目标方法获取拦截器链
    160          Object retVal;
    161          // Check whether we only have one InvokerInterceptor: that is,
    162          // no real advice, but just reflective invocation of the target.
    163          if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
    164             // We can skip creating a MethodInvocation: just invoke the target directly.
    165             // Note that the final invoker must be an InvokerInterceptor, so we know
    166             // it does nothing but a reflective operation on the target, and no hot
    167             // swapping or fancy proxying.
    168             Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    169             retVal = methodProxy.invoke(target, argsToUse);
    170          }
    171          else {
    172             // We need to create a method invocation...
    173             retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();//执行拦截器链
    174          }
    175          retVal = processReturnType(proxy, target, method, retVal);
    176          return retVal;
    177       }
    178       finally {
    179          if (target != null && !targetSource.isStatic()) {
    180             targetSource.releaseTarget(target);
    181          }
    182          if (setProxyContext) {
    183             // Restore old proxy.
    184             AopContext.setCurrentProxy(oldProxy);
    185          }
    186       }
    187    }
    188 }

    ?

    ?
      下面我们可以通过调试代码的方式来探究拦截器的调用。在这里拦截器是通过链式调用的方法按照顺序依次执行,我们可以通过时序图来很好的发现其调用逻辑。

      好了,不知道通过源码阅读大家有没有对Spring AOP有了一个全新的认识呢?有任何疑问欢迎留言喔~

    ?

      

    当前文章://www.wmdzr.com/brayg/index.html

    发布时间:2019-05-22 05:00:06

    可能与老虎伍兹一样是“性爱成瘾”患者! 我们对校园凶杀案反思的重大失误导致凶杀案连续发生! 青年创业者为什么失败几率高? 算一算,高考真实录取率到底有多低? 如果这都不算爱 怎么说呐,大家放心 人人都有“妄想症” 为什么说“女汉子”是一个伪命题?

    ?;ㄕ饫镒畋阋肆?,不信你来看 想知道哪里有出售紫藤的吗,来全国最大的紫藤产地吧 高度120公分剑麻苗多少钱一棵? 【优质货源】告诉你最好的天堂草价格多少钱一斤能买到 黑麦草有多少种? 夏天能种狗牙根草籽吗? 庭院草坪种什么草最好? 百慕大草坪的返青时间是什么时候? 二月可以种什么花卉种子? 什么草固土护坡好? 11月可以播种地肤吗? 梨树种子市场多少钱一斤? 哪里有出售北栾种子? 锦鸡儿种子播种前需要处理吗? 福建哪里有卖柠檬种子的? 栾树种子沙藏多长时间才能播种? 辽宁哪里有卖君迁子种子的? 江苏哪里有卖青桐种子的? 金森女贞与大叶女贞的区别是什么?

    编辑:安平马

      文章推荐

      分类排行榜

      专栏文章

      更多>

      服务推荐

      浙江十一选五开奖直播
      长期坚持早起是什么感觉? 扫一扫关注最新创业资讯
    • 更加紧密团结在以习近平同志为核心的党中央周围  2019-05-21
    • 马拉维“红旗飘飘”十年间,中国工程印上了当地纸币 2019-05-21
    • 庆祝人民日报创刊70周年系列访谈之颜世贵 2019-05-15
    • 国产新型雷达芯片华睿2号与组网中心同时亮相 2019-05-15
    • VRAR从热转凉 追风上市公司“跌落神坛”追风上市公司“跌落神坛”-手机行情 2019-05-06
    • The GNU General Public License v3.0 2019-05-05
    • 第21届上海国际电影节启幕 设“一带一路电影周” 2019-04-11
    • 广西壮族自治区东兰县“七民一站一阵地工作法”维护群众权益 2019-04-08
    • 苗山脱贫影像志——父母在 不远行 2019-04-08
    • 竹编:缝隙里的乡愁文章中国国家地理网 2019-03-31
    • “几乎是时时在流血、天天有牺牲”,他们的故事你知道吗? 2019-03-31