动态代理解析:https://blog.csdn.net/wonking666/article/details/79542820

一:Advice(通知)
(1)定义在连接点做什么,为切面增强提供织入接口。在spring aop中主要描述围绕方法调用而注入的切面行为。
(2)spring定义了几个时刻织入增强行为的接口
  =>org.springframework.aop.BeforeAdvice
   org.springframework.aop.MethodBeforeAdvice
  =>org.springframework.aop.AfterAdvice
   org.springframework.aop.AfterReturningAdvice
  =>org.springframework.aop.ThrowsAdvice

二:PointCut(切点)
(1)决定Advice应该作用那些连接点。也就是说通过PointCut来定义需要增强的方法集合。
(2)spring定义的PointCut的接口
  =>org.springframework.aop.Pointcut
  =>org.springframework.aop.TruePointcut
  => org.springframework.aop.support.JdkRegexpMethodPointcut
(3)相关接口。PointCut接口会返回两个对象,一个ClassFilter,一个是MethodMatcher
  =>org.springframework.aop.ClassFilter    
  =>org.springframework.aop.TrueClassFilter

  =>org.springframework.aop.MethodMatcher  匹配当前方法是否需要执行增强逻辑,也就是是否需要执行Advice接口的方法。
  =>org.springframework.aop.TrueMethodMatcher

三:通知器皿(Advisor)
  (1)完成对目标方法的切面增强设计(advice)和关注点的设计(PoinCut)以后,需要一个对象把他们结合起来,完成这个作用的就是(Advisor)
  (2)spring定义的Advisor接口
  =>org.springframework.aop.Advisor
      =>org.springframework.aop.PointcutAdvisor
      =>org.springframework.aop.support.DefaultPointcutAdvisor


  (3)Advisor的控制器的接口
  =>org.springframework.aop.framework.adapter.AdvisorAdapter
  =>org.springframework.aop.framework.adapter.AfterReturningAdviceAdapter  目标方法执行完执行该增强的控制器
  =>org.springframework.aop.framework.adapter.MethodBeforeAdviceAdapter  目标方法未执行前执行该增强的控制器
  =>org.springframework.aop.framework.adapter.ThrowsAdviceAdapter   目标方法执行过程抛出异常执行该增强的控制器

四:springAop的相关
  (1)springAop的核心技术是动态代理。动态代理的技术是jdk的一个特征。
  (2)springAop的代理对象生成案例
    =>org.springframework.aop.framework.ProxyFactoryBean
    =>org.springframework.aop.framework.ProxyFactory

五:ProxyFactoryBean的工作流程。
(1)实现FactoryBean接口的类,在想IOC容器申请bean的时候,其实返回的是该类执行getObject()方法的返回。
(2)ProxyFactoryBean的getObject()方法返回的是目标对象的代理对象。
  其执行过程
  =>根据配置的interceptorNames的属性值先初始化代理增强的链子.根据interceptorNames从IOC容器中得到增强类的bean,然后判断其类型,形成DefaultPointcutAdvisor对象。
  =>根据配置的targetName属性值从IOC容器中得到目标对象的bean,形成一个SingletonTargetSource对象。
  =>将其本身作为一个aop代理对象创建的数据配置类,创建一个动态代理对象,返回给ioc容器申请。
(3)在执行目标对象的方法过程中,会根据执行的方法的对象,从代理链子里找到所有的Advisor对象,然后利用其属性Pointcut对象获取ClassFilter, MethodMatcher来判断当前Advisor是否要执行。如果执行,则加入执行代理链子中。以jdk动态代理为例子,是org.springframework.aop.framework.JdkDynamicAopProxy类中invoke(Object proxy, Method method, Object[] args)方法中这句代码List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);。该句代码中this.advised其实就是ProxyFactoryBean本身。

六案例

一:Advice的对象

package com.mobile.thinks.aop.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class LoginBeforeAdvice implements MethodBeforeAdvice{

    @Override
public void before(Method method, Object[] args, Object target)throws Throwable {
System.out.println("LoginBeforeAdvice.before()执行方法为==>"+method.getName());
System.out.println("LoginBeforeAdvice.before()执行参数为==>"+args);
System.out.println("LoginBeforeAdvice.before()执行的目标为==>"+target.getClass());
} }

二:目标对象

package com.mobile.thinks.service.impl;

import java.util.Date;

import org.springframework.stereotype.Service;

import com.mobile.thinks.entity.User;
import com.mobile.thinks.service.UserInfoService; @Service(value="userInfoServiceImpl")
public class UserInfoServiceImpl implements UserInfoService{ @Override
public User loginByUserNameAndPassWord(String userName, String passWord) {
User user=new User(); user.setAddress("三门峡");
user.setAge(28);
user.setCreateTime(new Date());
user.setName(userName);
return user;
} }

三:配置文件

 <!-- 测试ProxyFactoryBean -->
<!--定义一个advice -->
<bean name="loginBeforeAdvice" class="com.mobile.thinks.aop.advice.LoginBeforeAdvice" />
<!-- 定义FactoryBean -->
<bean name="userInfoService" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 要代理的目标对象,在ioc容器中的名字 -->
<property name="targetName">
<value>userInfoServiceImpl</value>
</property>
<!-- 要植入增强功能的advice在IOC容器中的名字 -->
<property name="interceptorNames">
<list><value>loginBeforeAdvice</value></list>
</property>
</bean>

七:spring内部基于该中方式实现动态代理的案例。spring提供的HttpInvoker远程调用.可以阅读该类getObject方法。实现对Facade接口代理

org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean

==============================spring的自动进行对bean进行代理的创建类===============================

1、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

2、上述类是org.springframework.beans.factory.config.BeanPostProcessor接口的实现类

3、ioc在创建bean时,postProcessAfterInstantiation会执行方法,并对当前bean检查,是否需要代理。

4、检查逻辑,每一个切面,都会有自己的Pointcut,去适配当前的bean。需要则动态代理,不需要则返回。

事务管理实现动态代理的切面:

事务代理的切面:org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor

pointcut的类:org.springframework.transaction.interceptor.TransactionAttributeSourcePointcut

事务增强的类:org.springframework.transaction.interceptor.TransactionInterceptor

==============================spring的具体实现===============================

1、Advisor包换了Advice和Pointcut
2、Advice里是面向切面的增强逻辑实现
3、Pointcut里包含了ClassFilter和MethodMatcher。通过对类进行过滤或者方法进行过滤,决定一个类是否需要进行动态代理,添加增强逻辑。


1、spring容器中会注册:org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator

该类是org.springframework.beans.factory.config.BeanPostProcessor的实现,该类会在客户端向spring申请bean的时候,进行代理类的创建,

2、向spring容器中获取所有实现advisor接口的List<Advisor>。

3、org.springframework.aop.support.AopUtils类的findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz)

根据当前要被创建的bean的Class和beanName,去适配所有的List<Advisor>,看那些是适合当前bean的增强。

先根据advisor中的Pointcut的ClassFilter和MethodMatcher的方法决定

先根据ClassFilter决定,如ClassFilter决定不了,则根据MethodMatcher匹配bean的所有方法,包括接口和继承的类的方法。

4、通过2,3步确定那些List<Advisor>可以对当前bean进行动态代理增强,然后进行代理类的创建。

org.springframework.aop.framework.JdkDynamicAopProxy(代理类的执行入口)

org.springframework.aop.framework.ProxyFactory(所有适合当前List<Advisor>进行增强的信息会被存储到proxyFactory中)

org.springframework.aop.framework.AdvisedSupport是ProxyFactory的父类


spring的动态代理实现的基本逻辑
1、从ioc容器中找到所有实现了Advisor接口的bean,并将其缓存
2、扫描:每初始化一个bean,进行扫描的时候,都要用spring容器里的每一个Advisor里的Pointcut进行过滤,看当前类的是否需要进行增强。如果需要,把匹配通过的Advisor形成一个集合。
3、扫描后,如果返回的Advisor集合里不为空,说明该类需要代理,则创建代理对象。并将每一个Advisor里的Advice作为增强加入的增强链条中。(advice有排序功能,决定那个增强先被代理执行)

jdk动态代理的分析:https://www.cnblogs.com/huansky/p/9573202.html

												

【spring源码学习】spring的AOP面向切面编程的实现解析的更多相关文章

  1. spring源码学习之路---AOP初探(六)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 最近工作很忙,但当初打算学习 ...

  2. spring源码学习——spring整体架构和设计理念

    Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...

  3. 重新学习之spring第二个程序,配置AOP面向切面编程

    第一步:在配置好的ioc容器的基础上,导入面向切面编程所需要的jar包 (本案例用的是spring3.2.4,由于spring3.2.4的官网jar包中不再有依赖包,所以依赖包都是从网上找的) 第二步 ...

  4. Spring 源码学习(4) —— 动态AOP使用示例

    在实际工作中, 此bean可能是满足业务需要的核心逻辑, 例如test()方法中可能会封装着某个核心业务, 如果在test()方法前后加入日志来跟踪调试, 直接修改源码并不符合面向对象的设计模式, 而 ...

  5. Spring源码学习

    Spring源码学习--ClassPathXmlApplicationContext(一) spring源码学习--FileSystemXmlApplicationContext(二) spring源 ...

  6. Spring 源码学习——Aop

    Spring 源码学习--Aop 什么是 AOP 以下是百度百科的解释:AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程通过预编译的方式和运行期动态代理实 ...

  7. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  8. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  9. spring源码学习之路---IOC初探(二)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章当中我没有提及具体的搭 ...

随机推荐

  1. 介绍Web项目中用到的几款JQuery消息提示插件

    第一款 noty 官方网站:https://github.com/needim/noty 第二款 artDialog artDialog是一个精巧的web对话框组件,压缩后只有十多KB,并且不依赖其他 ...

  2. TCP的握手与挥手

    轻轻的TCP走了,正如TCP轻轻的来,TCP挥一挥手,传递了不知多少信息 看到哪,记到哪,想起哪,就看哪,这就是我的博客园,很随性 ---------------------------------- ...

  3. mongoose@4.5.2的eachAsync bug

    自称踩坑大王,幸好没有地雷,哈哈哈哈哈哈,今天用了mongoose的 eachAsync() 方法,没想到,会出现 Trace: [RangeError: Maximum call stack siz ...

  4. 深入理解JVM 垃圾收集器(下)G1收集器

    1.回顾CMS 1.1堆内存结构 1.2新生代GC 1.3老年代GC 2.G1收集器 2.1G1实现概览及使用场景 G1的推荐使用场景 2.2GC 2.2.1新生代GC 2.2.2老年代GC 老年代G ...

  5. 简单介绍java Enumeration(转)

    Enumeration接口 Enumeration接口本身不是一个数据结构.但是,对其他数据结构非常重要. Enumeration接口定义了从一个数据结构得到连续数据的手段.例如,Enumeratio ...

  6. ()IT 职场经验)一位10年Java工作经验的架构师的经验分享,感觉很受用。

    阿里巴巴技术大牛黄勇的经验分享,感觉很受用. 关于IT 职场经验 1. 把技术当成工具 技术这东西,其实一点都不神秘,它只不过是一个工具,用这个工具可以帮助我们解决实际问题,就这么简单. 我们每天在面 ...

  7. 微信小程序选择器

  8. 前端开发日记之jQuery

    优先引入CDN上的jQuery,如果失效再引入本地的jQuery! <script src="http://libs.baidu.com/jquery/1.11.1/jquery.js ...

  9. Android中获取屏幕高度和宽度

    有时我们需要获取当前屏幕的高度和宽度,只需要在一个Activity的onCreate()方法中写上如下代码即可: //定义DisplayMetrics 对象 DisplayMetrics metric ...

  10. PlusOne

    问题描述:一个数组每一位代表一个数字的每一位.数字高位在数组的低位.求数字加1后得到新数组. 算法分析:要从数组的高位到低位进行遍历. public class PlusOne { public in ...