欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

JavaAOP动态代理详细介绍,

来源: javaer 分享于  点击 34762 次 点评:249

JavaAOP动态代理详细介绍,


目录
  • 1.IOC与AOP概念
  • 2.为何使用动态代理
    • 2.1 JDK原生动态代理
      • 2.1.1 MathService接口类
      • 2.1.2 MathServiceImpl实现接口类
      • 2.1.3 ProxyFactory动态代理工厂
      • 2.1.4 测试类
    • 2.2 cglib动态代理
      • 2.2.1 MathServiceImpl类
      • 2.2.2 ProxyFactory动态代理工厂
      • 2.2.3 测试类
  • 3.AOP动态代理
    • 3.1 添加对应依赖
      • 3.2 配置spring.xml文件
        • 3.3 MathService接口类
          • 3.4 MathServiceImpl实现接口类
            • 3.5 LogAspect类
              • 3.6 测试类

              1.IOC与AOP概念

              IOC:控制反转,把对象创建和对象之间的调用过程,交给Spring进行管理。使用IOC的目的是为了降低耦合度。

              AOP:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP的底层实现是基于动态代理(实现方式是当切入接口时,使用JDK原生动态代理;当切入普通方法时,使用cglib动态代理)。

              2.为何使用动态代理

              随着业务的不断扩展:

              (1)日志功能:如果日志代码修改,需要修改多处。

              (2)校验功能:如果多处需要校验,需要修改多处。

              这时就需要使用动态代理来解决问题,动态代理的实现方式有两种:

              [1]JDK原生动态代理:缺点是必须基于接口完成

              [2]cglib动态代理:他可以不用基于接口完成

              2.1 JDK原生动态代理

              2.1.1 MathService接口类

              public interface MathService {
                  //+
                  public Double add(double a,double b);
                  //-
                  public Double sub(double a,double b);
                  //*
                  public Double mul(double a,double b);
                  ///
                  public Double div(double a,double b);
              }

              2.1.2 MathServiceImpl实现接口类

              public class MathServiceImpl implements MathService{
                  @Override
                  public Double add(double a, double b) {
                      Double result=a+b;
                      return result;
                  }
                  @Override
                  public Double sub(double a, double b) {
                      Double result=a-b;
                      return result;
                  }
                  @Override
                  public Double mul(double a, double b) {
                      Double result=a*b;
                      return result;
                  }
                  @Override
                  public Double div(double a, double b) {
                      Double result=a/b;
                      return result;
                  }
              }

              2.1.3 ProxyFactory动态代理工厂

              public class ProxyFactory {
                  //被代理对象
                  private Object target;
                  public ProxyFactory(Object target) {
                      this.target = target;
                  }
                  //获取代理对象
                  public Object getProxy(){
                      /**
                       * ClassLoader loader, 被代理对象的类加载器
                       * Class<?>[] interfaces, 被代理对象实现的接口
                       * InvocationHandler h: 当代理对象执行被代理的方法时,会触发该对象中的invoke功能
                       */
                      ClassLoader loader=target.getClass().getClassLoader();
                      Class<?>[] interfaces=target.getClass().getInterfaces();
                      InvocationHandler h=new InvocationHandler() {
                          @Override
                          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                              //可以加上需要的非业务代码
                              //method.getName()获取方法名
                              // Arrays.asList(args)获取输入值
                              System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
                              //method:表示代理对象要代理的方法
                              //invoke:回调该函数
                              //args:方法需要的参数
                              Object result = method.invoke(target, args);//代理对象回调该方法
                              return result;
                          }
                      };
                      //先写此处方法,才可找到上述三个方法填写方式
                      Object o = Proxy.newProxyInstance(loader, interfaces, h);
                      return o;
                  }
              }

              2.1.4 测试类

              public class Test01 {
                  public static void main(String[] args) {
                      MathServiceImpl target=new MathServiceImpl();
                      ProxyFactory proxyFactory=new ProxyFactory(target);
                      MathService proxy = (MathService) proxyFactory.getProxy();
                      Double add = proxy.add(15.0, 5.0);
                      System.out.println(add);
                  }
              }

              2.2 cglib动态代理

              2.2.1 MathServiceImpl类

              public class MathServiceImpl{
                  public Double add(double a, double b) {
                      Double result=a+b;
                      return result;
                  }
                  public Double sub(double a, double b) {
                      Double result=a-b;
                      return result;
                  }
                  public Double mul(double a, double b) {
                      Double result=a*b;
                      return result;
                  }
                  public Double div(double a, double b) {
                      Double result=a/b;
                      return result;
                  }
              }

              2.2.2 ProxyFactory动态代理工厂

              注意:

              (1)引入cglib的jar包.

              <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>3.2.5</version>
              </dependency>  

              (2)创建一个代理类工厂并实现接口MethodInterceptor

              public class ProxyFactory implements MethodInterceptor {
                  private Object target;
                  public ProxyFactory(Object target) {
                      this.target = target;
                  }
                  //获取代理对象
                  public Object getProxy(){
                      Enhancer enhancer=new Enhancer();
                      //指定被代理对象的父类
                      enhancer.setSuperclass(target.getClass());
                      //指定回调类
                      enhancer.setCallback(this);
                      //创建代理对象
                      return enhancer.create();
                  }
                  //当代理对象执行代理方法时触发的方法
                  public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
              //        System.out.println("before++++++++++++++++++++");
              //        Object result = method.invoke(target, args);
                      //可以加上需要的非业务代码
                      //method.getName()获取方法名
                      // Arrays.asList(args)获取输入值
                      System.out.println("this is "+method.getName()+" method begin with"+ Arrays.asList(args));
                      //method:表示代理对象要代理的方法
                      //invoke:回调该函数
                      //args:方法需要的参数
                      Object result = method.invoke(target, args);//代理对象回调该方法
                      return result;
                  }
              }

              2.2.3 测试类

              public class Test01 {
                  public static void main(String[] args) {
                      MathServiceImpl target=new MathServiceImpl();
                      ProxyFactory proxyFactory=new ProxyFactory(target);
                      MathServiceImpl proxy = (MathServiceImpl) proxyFactory.getProxy();
                      Double add = proxy.add(1, 2);
                      System.out.println(add);
                  }
              }

              3.AOP动态代理

              3.1 添加对应依赖

              <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-webmvc</artifactId>
                    <version>5.2.15.RELEASE</version>
                  </dependency>
                  <dependency>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-aspects</artifactId>
                    <version>5.2.15.RELEASE</version>
                  </dependency>

              3.2 配置spring.xml文件

              <?xml version="1.0" encoding="UTF-8"?>
              <beans xmlns="http://www.springframework.org/schema/beans"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xmlns:context="http://www.springframework.org/schema/context"
                     xmlns:aop="http://www.springframework.org/schema/aop"
                     xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans.xsd
                     http://www.springframework.org/schema/context
                     https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
                  <!--包扫描-->
                  <context:component-scan base-package="com.qy151wd.proxy.proxy.aop"/>
                  <!--开启aop注解-->
                  <aop:aspectj-autoproxy/>
              </beans>

              3.3 MathService接口类

              public interface MathService {
                  public Double add(double a, double b);
                  public Double sub(double a, double b);
                  public Double mul(double a, double b);
                  public Double div(double a, double b);
              }

              3.4 MathServiceImpl实现接口类

              @Service
              public class MathServiceImpl implements MathService {
                  @Override
                  public Double add(double a, double b) {
                      Double result=a+b;
                      return result;
                  }
                  @Override
                  public Double sub(double a, double b) {
                      Double result=a-b;
                      return result;
                  }
                  @Override
                  public Double mul(double a, double b) {
                      Double result=a*b;
                      return result;
                  }
                  @Override
                  public Double div(double a, double b) {
                      Double result=a/b;
                      return result;
                  }
              }

              3.5 LogAspect类

              @Service //若是使用@component也可以
              @Aspect //表示该类为切面类
              public class LogAspect {
                  //任意返回类型 aop包下的所有类都有切面日志 使用通配符
                  //第一个*:修饰符和返回值类型
                  //第二个*:所有类
                  //第三个*:所有方法
                  @Before("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")
                  public void before(){
                      System.out.println("方法执行前的日志");
                  }
                  @After("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))") //总会被执行,不管有没有异常
                  public void after(){
                      System.out.println("方法执行后的日志");
                  }
                  @AfterReturning("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//只有碰到return后才会执行
                  public void afterReturning(){
                      System.out.println("碰到return后执行");
                  }
                  @AfterThrowing("execution(* com.qy151wd.proxy.proxy.aop.*.*(..))")//异常通知
                  public void afterThrowing(){
                      System.out.println("出现异常了");
                  }
              }

              3.6 测试类

              public class Test01 {
                  public static void main(String[] args) {
                      //从spring容器中获取
                      ApplicationContext app=new ClassPathXmlApplicationContext("spring.xml");
                      MathService mathService = (MathService) app.getBean("mathServiceImpl");
                      Double add = mathService.add(10, 5);
                      System.out.println(add);
                  }
              }

              到此这篇关于Java AOP动态代理详细介绍的文章就介绍到这了,更多相关Java AOP动态代理内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

              您可能感兴趣的文章:
              • Java JDK动态代理(AOP)用法及实现原理详解
              • Java动态代理和AOP应用示例
              • Java JDK动态代理(AOP)的实现原理与使用详析
              • java使用动态代理来实现AOP(日志记录)的实例代码
              • Java动态代理实现AOP
              相关栏目:

              用户点评