spring之AOP简介与原理

   一、AOP基本情况

         AOP 为Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架的一个重要内容,是函数编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提供程序的可重用性,同时提高的开发的效率。

       AOP 采用横向抽取机制,取代了传统的纵向继承体系重复代码。

       经典应用:事物管理、性能监视、安全检查、缓存、日志等。

     

      SpringAOP 使用纯JAVA实现,不需要专门的编译过程和类加载器,在运行期通过代理的方式向目标类织入增强代码。

      AspectJ是一个基于JAVA语音的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了JAVA语音,提供了一个专门的编辑器,在编译时提供横向代码的织入。

    二 AOP的实现原理

         aop底层将采用代理机制进行实现。

         1、接口+实现类:spring 采用JDK的动态代理Proxy

         2实现类:spring采用 cglib 字节码增强。

         

   AOP原理之一DK的动态代理Proxy

         其是对装饰者设计模式的简化 使用前提是必须有接口

       1目标类:接口+实现类

      //接口

  public interface IUserService {
  public void addUser();
  public void updateUser();
  public void deleteUser();
  }

  //实现类

public class UseServiceImpl implements IUserService {
public void addUser() {
System.out.println(“增加用户的方法”);
}
public void updateUser() {
System.out.println(“更改用户的方法”);

}
public void deleteUser() {
System.out.println(“删除用户的方法”);

}

}

2 切面类:y用于存放通知的advice

public class MyAspect {
public void before(){
System.out.println(“advice前置通知”);
}
public void after(){
System.out.println(“advice后置通知”);
}

}

3 代理类:由工厂生成 工厂类编写工厂类

public class MyBeanFactory {
/**
* @return
*/
public static IUserService createUserviceImpl(){
//目标类target
final IUserService userService =new UseServiceImpl();
//切面类 aspect里面还有advice通知
final MyAspect myAspect = new MyAspect();

/**
* 代理类将 目标类(切入点)和切面类(通知ADVICE)结合》》切面
* 代理类Proxy.newProxyInstance(loader, interfaces, h);
* 参数1:  loader 类加载器,动态代理运行时创建,任何类都需要类加载器将其加载到内存中
* 参数2:interfaces  Class[] interfaces 代理类需要实现的所有接口
*   方式1: 目标类实例.getClass.getInterfaces();注意只能获得自己接口,不能获得父元素接口
*   方式二:new Class[]{UserService.class}
*       例如:Jdbc 驱动–>DriverManager 获得接口的Connection
* 参数3: InyocationHandler 处理类,接口,必须进行实现类,一般采用匿名内部类
*       提供Invoke方法,代理类的每一个方法执行时,都将调用一次invoke
*        参数31 :Object proxy :代理对象
*        参数32: Method method:代理对象当前执行的方法的描述对象(反射)
*               执行方法名: method.getName()
*               执行方法:method.invoke(对象,实际参数)
*        参数33: Object[] args: 方法实际参数
*/
IUserService proxyUserService = (IUserService) Proxy.newProxyInstance(MyBeanFactory.class.getClassLoader(),
  userService.getClass().getInterfaces(),
  //匿名内部类
new InvocationHandler() {

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//执行前置方法
myAspect.before();

   // 执行目标方法  jionpoint连接点 pointcut 切入点
   Object object= method.invoke(userService, args);

//执行后置方法
myAspect.after();
return object;
}
});
return proxyUserService;
}

}

AOP原理之一cglib 字节码增强

   不要使用接口了。

   1、不需要接口,只有实现类

  2、采用字节码增强框架cglib 在运行时创建目标类的子类,从而对目标类进行增强。

  导入JAR包

      核心为cglib/cglib-2.2.jar

     依赖为asm-3.3.jar

  这些包spring-core.jar已经包含了。

public class MyBeanFactoryCglib {
/**
* cglib字节码增强
*  crtl+shift +o导包
*  crtl+T查看子类
* @return
*/
public static UseServiceImpl createUserviceImpl(){
//目标类target 
final UseServiceImpl userServiceImpl =new UseServiceImpl();
//切面类 aspect里面还有advice通知
final MyAspect myAspect = new MyAspect();

//3 代理类 ,采用cglib,底层创建目标的子类
//3.1核心类
Enhancer enhancer = new Enhancer();
//3.2确定父类 父类就是要被代理的类。
enhancer.setSuperclass(userServiceImpl.getClass());
/*
* 3.3设置回调函数,MethodInterceptor接口 等效 jdk InvocationHandler接口
*   intercept() 等效JDK invoke()
*    参数1 参数2、参数3 以invoke 一样
*    参数4:methodProxy 方法的代理
*    
*/

enhancer.setCallback(new MethodInterceptor() {

public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
//前 
myAspect.before();

//执行目标类的方法 第一种方法
Object  obj = method.invoke(userServiceImpl, args);
//执行代理类的父类,执行目标类(目标类和代理类 父子关系)第二种方法
methodProxy.invokeSuper(proxy, args);
//后
myAspect.after();
return obj;
}
});

//3.4创建代理
UseServiceImpl  proxService = (UseServiceImpl) enhancer.create();
return proxService;
}

}



    原文作者:AOP
    原文地址: https://blog.csdn.net/qq_36697880/article/details/80945693
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞