SpringAop概念

当前仅想着能用简单了解一下,后续再深入研究,如果文中出现错误,希望好心人评论指正。

 

 
 
AOP : 面向切面编程
 
AOP底层实现:基于JDK的动态代理和基于Cglib的动态代理
 
AOP 开发明确的事项
 
   1. 需要编写的代码
    1.1 编写核心业务代码 (目标类的目标方法)
    1.2 编写切面类,切面类中有通知(增强功能方法)
    1.3 在配置文件中,配置织入关系,即将哪些通知与哪些连接点进行结合
 
   2.AOP 技术实现的内容
    Spring框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码运行逻辑。
 
     3.AOP底层使用哪种代理方式
    在spring中,框架会根据目标是否实现了接口来决定采用哪种动态代理的方式。
    *JDK 的动态代理:  针对实现了接口的类产生代理。
    *CGlib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象
 
AOP术语
 
  Tatget(目标):被增强的对象
 
  Proxy(代理): 一个类被AOP织入增强后,就产生一个结果代理类
 
  Joinpoint(连接点):指的是可以被拦截到的点,在Spring中这些点指的是方法,因为Spring只支持方法类型的连接点
  *增删改查这些方法都可以增强,这些方法称为连接点
 
  Pointcut(切入点):所谓的切入点是指我们要对哪些连接点进行拦截的定义
  *只想对save方法进行增强,save方法被称为是切入点。
 
  Advice(通知/增强):拦截后要做的事情,封装增强业务逻辑的方法
  *对save方法要进行权限校验,权限校验的方法称为是通知。
 
  Aspect(切面):就是切入点和通知的组合\结合
 
  Weaving(织入) : 将Advice应用到Target的过程 是指把增强应用到目标对象来创建新的代理对象的过程。Spring采用动态代理织入,而Aspectj采用编译期织入和类装载期植入。
  *将权限校验应用到UserDaoImpl的save方法的这个过程
 
 
 
 
 
 
 
 
 

CGLib动态代理实现原理

  利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

 
CGLIB 动态代理 示例:
package com.zhan.proxy.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class ProxyTest {
    public static void main(String[] args) {
        //目标对象
        final Target target = new Target();
        //增强对象
        final Advice advice = new Advice();

        //返回值就是动态生成的对象 基于cglib
        //1.创建增强器
        Enhancer enhancer = new Enhancer();
        //2.设置父类(目标)
        enhancer.setSuperclass(Target.class);
        //3.设置回调
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                advice.before();
                Object invoke = method.invoke(target, args);
                advice.afterReturing();
                return invoke;
            }
        });
        //4.创建代理对象
        Target proxy = (Target) enhancer.create();
        proxy.save();
    }
}

 

 

 

 

JDK动态代理实现原理

  通过实现InvocationHandler接口创建自己的调用处理器;

  通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理;

  通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;

  通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;

  JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,Spring通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。

 

JDK动态代理示例:

package com.zhan.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        final Target target = new Target();
        final Advice advice = new Advice();
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        advice.before();
                        Object invoke = method.invoke(target, args);
                        advice.afterReturing();
                        return invoke;
                    }
                }
        );
        proxy.save();
    }
}

 

 

posted @ 2021-02-25 16:49  year12  阅读(80)  评论(0编辑  收藏  举报