Java AOP动态代理详细介绍

目录
  • 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动态代理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java使用动态代理来实现AOP(日志记录)的实例代码

    下面是一个AOP实现的简单例子: 首先定义一些业务方法: 复制代码 代码如下: /** * Created with IntelliJ IDEA. * Author: wangjie  email:tiantian.china.2@gmail.com * Date: 13-9-23 * Time: 下午3:49 */public interface BussinessService {    public String login(String username, String password

  • Java动态代理实现AOP

    目前整个开发社区对AOP(Aspect Oriented Programing)推崇备至,也涌现出大量支持AOP的优秀Framework,--Spring, JAC, Jboss AOP 等等.AOP似乎一时之间成了潮流.Java初学者不禁要发出感慨,OOP还没有学通呢,又来AOP.本文不是要在理论上具体阐述何为AOP, 为何要进行AOP . 要详细了解学习AOP可以到它老家http://aosd.net去瞧瞧.这里只是意图通过一个简单的例子向初学者展示一下如何来进行AOP. 为了简单起见,例子

  • Java JDK动态代理(AOP)用法及实现原理详解

    Java-JDK动态代理(AOP)使用及实现原理分析 第一章:代理的介绍 介绍:我们需要掌握的程度 动态代理(理解) 基于反射机制 掌握的程度: 1.什么是动态代理? 2.动态代理能够做什么? 后面我们在用Spirng和Mybatis的时候,要理解怎么使用的. 1.什么是代理? 代理,在我们日常生活之中就有体现,代购,中介,换ip,商家等等. 比如有一家美国的大学,可以对全世界招生.留学中介(代理 ) 留学中介(代理):帮助这家美国的学校招生,中介是学校的代理中介是代替学校完成招生功能 代理特点

  • Java JDK动态代理(AOP)的实现原理与使用详析

    本文主要给大家介绍了关于Java JDK动态代理(AOP)实现原理与使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 一.什么是代理? 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 代理模式UML图: 简单结构示意图: 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别.通过代理类这中间一层,能有效控制对委托类对

  • Java动态代理和AOP应用示例

    本文实例讲述了Java动态代理和AOP应用.分享给大家供大家参考,具体如下: 一 点睛 动态代理在AOP(Aspect Orient Program,即面向切面编程)里被称为AOP代理,AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法.但AOP代理中的方法与目标对象的方法存在差异:AOP代理里的方法可以在执行目标方法之前.之后插入一些通用处理. 二 代码 Dog.java public interface Dog { // info方法声明 void info(); // run方法

  • Java AOP动态代理详细介绍

    目录 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

  • Spring AOP代理详细介绍

    Spring AOP代理详细介绍 前言: 一开始我对spring AOP还是属于一知半解的状态,这几天遇到一个问题,加上又查看了一些Spring相关知识,感觉对这个问题有了更深刻的认识.所以写下来分享一下. 我们知道,Spring支持多种AOP方式,Spring自己的基于代理的AOP和AspectJ的基于编织(weaving)的AOP.如果一个类实现了一个或多个接口,那么Spring就会使用默认的JDK动态代理,如果没有实现任何接口,就会使用cglib来代理.当然我们也可以手动改变这些设置.这也

  • Java动态代理简单介绍

    目录 1.代理模式 2.静态代理实现 3.动态代理实现 1.代理模式 当我们需要调用某个类(具体实现类)的方法时,不直接创建该类的对象,而是拿到该类的代理类对象,通过代理对象,调用具体实现类的功能.具体实现类和代理类都实现同样的接口,并且代理类持有实现类的对象.这样做在调用端和具体实现端,做了一层隔离,避免直接打交道. 代理模式在现实中也有很多类似的例子,比如我们买房租房,都得通过中介,这个中介就相当于代理. 2.静态代理实现 1)定义接口: public interface IHouse {

  • Java JDK 动态代理的使用方法示例

    本文主要和大家分享介绍了关于Java JDK 动态代理使用的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 前言 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. Spring AOP的实现对于接口来说就是使用的JDK的动态代理来实现的,而对于类的代理使用CGLIB来实现. JDK的动态代理,就是在程序运行的过程中,根据被代理的接口来动态生成代理类的class文

  • 详解java中动态代理实现机制

    代理模式是常用的java设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. JAVA各种动态代理实现的比较 接口 interface AddInterface{ int add(int a, int b); } interface SubInterfa

  • java 中动态代理机制的实例讲解

    java 中动态代理机制的实例讲解 在学习Spring的时候,我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制,所以本篇随笔就是对java的动态机制进行一个回顾. 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)

  • java实现动态代理方法浅析

    一些Java项目中在mybatis与spring整合中有MapperScannerConfigurer的使用,该类通过反向代理自动生成基于接口的动态代理类. 有鉴于此,本文浅析了java的动态代理. 本文使用动态代理模拟处理事务的拦截器. 接口: public interface UserService { public void addUser(); public void removeUser(); public void searchUser(); } 实现类: public class

  • JAVA使用动态代理对象进行敏感字过滤代码实例

    这篇文章主要介绍了JAVA使用动态代理对象进行敏感字过滤代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 package com.hopetesting.web.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.BufferedReader; import java.io.FileNotFoundExcepti

随机推荐