Day2:Spring-AOP

代理模式:
其实就是使用另外一个对象去执行目标对象需要执行的动作,但是这个动作放在目标对象里面又不太合适,因此此时需要引入代理模式。 Spring中运行代理模式的主要是Spring-Security
例子:目标对象是访问客户端的用户,权限就是切面,权限的认证就是切入点,权限反馈的信息就是通知,用户与权限的关系就是连接点,前置通知、后置通知等都是用户与权限的关系有关。
代理对象的方法=目标对象的目标方法+通知

织入:形成代理对象的方法的过程

注意事项:
* 通知实际上是切面中的方法
* 只有符合切入点的目标方法才能加通知
* 连接点是目标对象或者代理对象的其中的方法
 
* 在jdk中,只要实现了InvocationHandler这个接口的类就是一个拦截器类
 * 作用:控制目标对象的目标方法的执行
 * @author Administrator
 * 拦截器的作用:
 *   *  引入类
 *        1、引入目标类
 *        2、引入安全性的类
 *        3、引入日志类
 *        4、引入权限类
 *   *  调用构造函数给对象赋值
 *   *  在invoke方法中把所以的逻辑结合在一起

* 1、代理对象是由谁产生的?jvm产生的
 * 2、代理对象实现了什么接口?实现了SalaryService接口
 * 3、代理对象的方法体是什么?
 *      代理对象的方法体中的内容就是拦截器中invoke方法中的内容
 * 4、拦截器中的invoke方法中的method参数是在什么时候赋值的?
 *      在客户端,代理对象调用方法实际上进入的是拦截器中的invoke方法,这个时候
 *      拦截器中的invoke方法中的method参数会被赋值

动态代理:
   动态代理分为两种:
      *  jdk的动态代理
         *  代理对象和目标对象实现了共同的接口
         *  拦截器必须实现InvocationHanlder接口

      *  cglib的动态代理
         *  代理对象是目标对象的子类
         *  拦截器必须实现MethodInterceptor接口
         *  hibernate中session.load采用的是cglib实现的

springAOP:xml
   *  在配置文件中:
       *  目标类
           <bean id="personDao" class="..PersonDaoImpl">
       *  切面
           <bean id="transaction" class="..Transaction">
       * aop:config
            <aop:config>
               //切入点
               <aop:pointcut>
               //切面
               <aop:aspect>
                  //配置通知
                  前置通知
                        method  切面中的方法
                           参数为:JoinPoint
                             从这个参数中可以得到目标方法的信息
                        point-ref  指向切入点
                  <aop:before method="" pointcut-ref>
                  后置通知
                       method
                       point-ref
                       returning  
                            returning="val"和后置通知有一个参数,这个参数可以获取方法的返回值,所以
                            参数的类型必须为Object,名称和val一致。
                       如果目标方法遇到异常,则不执行
                  <aop:after-returning>
                  最终通知
                       如果目标方法存在异常,则执行
                  <aop:after>
                  环绕通知
                       控制目标对象的目标方法的执行
                       环绕通知的方法的参数为:ProceedingJoinPoint
                           ProceedingJoinPoint.proceed 执行目标方法
                  <aop:around>
                  异常通知
                      可以获取目标方法产生的异常信息
                      throwing="ex"中的ex和异常通知的方法中的参数Throwable的名称保持一致。
                  <aop:throwing throwing="ex">
               </aop:aspect>
            </aop:config>

    *  在客户端,如果得到的bean的对象有代理对象,则返回代理对象

    *  注意事项
      
             *  如果切入点表达式的类写得不正确,则直接报错,找不到该类
             *  如果切入点表达式的方法写错了,则客户端直接返回该bean的对象
             *  spring的aop的原理可以采用两种形式产生代理对象
                   *  如果目标类实现接口,则spring会采用jdk动态代理
                   *  如果目标类没有实现接口,则采用cglib动态代理
             *  针对一个目标类,切面可以有很多个
切面的扫描:
1、导入springAOP的注解解析器
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2、导入类扫描的注解解析器
<context:component-scan base-package="cn.itcast.spring0401.aop.annotation"></context:component-scan>
总结原理:
当启动spring容器的时候,spring容器解析配置文件
*  就会解析到类扫描的注解解析器,会在base-package指定的包及子包中扫描所有的类,看类上是否有@Compontent,@Service,@Controller,@Repository注解,
*  如果有,则spring容器创建该类的实例
*  解析到aop的注解解析器,会在纳入spring管理的bean中,看哪个类上面是否有@Aspect注解
*  如果有,则会在方法中查找@Pointcut,就会找到切入点表达式,根据切入点表达式,在纳入spring范围的bean内查找,看哪个bean符合切入点表达式,如果符合则创建代理对象
当客户端访问某一个bean时,如果该bean有代理对象,则返回代理对象,否则返回该bean的对象
*  注解解析器:
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
*  支持的注解:
    @Aspect  @Before  @After  @Pointcut  @AfterReturning
    @Around   @AfterThrowing
原文地址:https://www.cnblogs.com/vijay/p/3526117.html