springAop之动态代理之一jdk技术实现原理即代码解读

Aop

简介:

Aop(Aspect Oriented Programming)面向切面编程,是OOP面向对象编程的一种补充将程序中交叉业务(事务,日志)代码提取出来,封装成切面,由AOP容器在适当时机位置将封装成的切面动态的织入到具体业务逻辑中。

AOP不是spring特有的。

应用场合:适用于具有横切逻辑的场合,如事务管理,日志记录,性能检测,异常通知,访问控制等。

作用:

不改变原有代码的基础动态添加新的功能。

模块化。

术语:

连接点(JoinPoint):程序执行的某个特定位置,如方法调用前,方法调用后,方法抛出异常时,方法调用前后等。

切入点(PointCut):定位位置找到需要切入的连接点,即切点。

增强Advice也称为通知: 在切点上执行的一段代码用来实现某些功能。

目标对象 Target :将执行增强处理的目标类。

织入(Weaving) :将增强添加到目标类具体切入点的过程。

代理(Proxy) :一个类被织入增强后,会产生一个代理类。

切面 Aspect :切点和增强的组合。

引介 Introduction 也称为引入。

实现原理

代理模式:

概念:为其他对象提供一种代理,以控制对这个对象的访问,起到中介的作用,通过代理对象访问目标对象,可以增强额外的操作,扩展目标对象的功能。

分类:

静态代理:代理类是程序员创建或工具生成的,所谓静态代理就是程序运行之前就已经存在代理类的字节码文件。缺点:代理对象需要和目标对象实现相同的接口,如果接口增加方法,目标对象和代理对象都要维护。

动态代理:代理类是程序在运行期间由JVM根据反射等机制动态生成的,自动生成代理类和代理对象,所谓动态就是在程序运行之前不存在代理类的字节码文件。

代理三要素:

一:实现目标类的接口。

二:初始化目标类的实例。

三:交叉业务,要执行的操作。

动态代理:

JDK技术:

proxy.newProxyInstance(

classloader 目标类的类加载器

interfaces 目标类得到接口列表

InvocationHandler 交叉业务逻辑

)

缺点:目标对象必须实现一个或多个接口,如果没有实现接口,则无法使用JDK的动态代理,此时可以使用cglib技术
代码
书写UserService接口

package springaop01.service;


/**
 * package_name:springaop01.service
 *
 * author:徐亚远 Date:2020/2/18 18:29
 * 项目名:springDemo01
 * Description:
 **/
public interface UserService {

    /**
     * @Author : 徐亚远
     * @Date : 2020/2/18 20:34
     * @param username
     * @param password
     * @Description :
     */
    void login(String username, String password);
}

书写UserService的实现类UserServiceImpl

package springaop01.service.impl;

import springaop01.service.UserService;

/**
 * package_name:springaop01.service.impl
 * Author:徐亚远
 * Date:2020/2/18 18:29
 * 项目名:springDemo01
 * Desription:
 **/
public class UserServlceImpl implements UserService {


    /**
     * @param password
     * @param username
     * @Author : 徐亚远
     * @Date : 2020/2/18 21:03
     * @Description :
     */

    @Override
    public void login(String username, String password) {
        System.out.println("loginUserServiceImpl登录:" + username + "    " + password);
    }
}

书写测试类使用jdk动态代理技术

package springaop01.controller;

import springaop01.service.UserService;
import springaop01.service.impl.UserServlceImpl;

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

/**
 * package_name:springaop01.controller
 * @author:徐亚远
 * Date:2020/2/18 18:41
 * 项目名:springDemo01
 * Description:
 **/
public class UserController {
    public static void main(String[] args) {
        /** 动态代理*/
        UserService userService = (UserService) Proxy.newProxyInstance(
                //目标类的类加载器
                UserServlceImpl.class.getClassLoader(),
                //目标类的接口
                new Class[]{UserService.class},
                //交叉业务
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("打印日志:" + method.getName() + " start at: [" + System.currentTimeMillis()
                                +"]"+"   "+"args:"+Arrays.toString(args));
                        Object object = method.invoke(new UserServlceImpl(), args);
                        return object;
                    }
                }
        );
        userService.login("admin", "admin");


    }
}

实现结果如图:
在这里插入图片描述

发布了64 篇原创文章 · 获赞 1 · 访问量 891

猜你喜欢

转载自blog.csdn.net/weixin_43311650/article/details/104394254
今日推荐