首页 > 其他分享 >代理和AOP

代理和AOP

时间:2023-03-26 16:12:52浏览次数:33  
标签:java String Greeting 代理 AOP import public greeting

代理是一种设计模式,在软件设计中,有时候会出现用户不想或者不能直接引用一个对象的情况,这时候就可以通过代理对象在用户和目标对象之间充当一个中介的作用。

静态代理

// 定义接口
public interface Greeting {
    void sayHello(String name);
}

// 实现类
public class GreetingImpl implements Greeting {
    @Override
    public void sayHello(String name) {
        System.out.println("hello: " + name);
    }
}

// 调用
public class Client {
    public static void welcome(Greeting greeting, String name){
        greeting.sayHello(name);
    }

    public static void main(String[] args) {
        Greeting greeting = new GreetingImpl();
        welcome(greeting, "java");
    }
}

// 结果:hello: java

// 在不修改实现类的情况下,给输出增加日志功能
// 创建代理类
public class GreetingProxy  implements Greeting{
    private Greeting greeting;

    public GreetingProxy(Greeting greeting){
        this.greeting = greeting;
    }

    @Override
    public void sayHello(String name) {
        System.out.println("method start");
        greeting.sayHello(name);
        System.out.println("method end");
    }
}

// 再次调用
public class Client {
    public static void main(String[] args) {
        Greeting greeting = new GreetingImpl();
        GreetingProxy proxy = new GreetingProxy(greeting);
        proxy.sayHello("java");
    }
}

// 输出
method start
hello: java
method end

动态代理

// 创建动态代理
public class LogHandler implements InvocationHandler {
    private Object originObj;

    public Object bind(Object originObj){
        this.originObj = originObj;
        return Proxy.newProxyInstance(
                originObj.getClass().getClassLoader(),
                originObj.getClass().getInterfaces(),
                this
        );
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(method.getName() + ": start");
        Object result = method.invoke(originObj, args);
        System.out.println(method.getName() + ": end");
        return result;
    }
}

// 调用
public class Client {
    public static void main(String[] args) {
        Greeting greeting = new GreetingImpl();

        LogHandler handler = new LogHandler();
        Greeting proxy = (Greeting) handler.bind(greeting);
        proxy.sayHello("java");
    }
}

// 结果
sayHello: start
hello: java
sayHello: end

AOP

SpringAOP可以帮助我们在在不修改源代码的前提下实现功能增强,底层实现基于动态代理或者CGLIB

依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

定义注解

package com.yungua.springboot.anno;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {
}

定义切面

package com.yungua.springboot.aspect;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

// 当前对象是一个切面
@Aspect
// 允许在SpringIOC对当前对象实例化并管理
@Component
@Slf4j
public class MethodExporterAspect {

    // 任何增加了@MethodExporter自定义注解的方法都将在执行前执行该切面方法
    // @Around环绕通知,可以控制方法入参、执行、返回结果等各方面细节
    @Around("@annotation(com.yungua.springboot.anno.MethodExporter)")
    public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable {
        long st = System.currentTimeMillis();
        // 执行目标方法,获取返回值
        Object proceed = joinPoint.proceed();
        long et = System.currentTimeMillis();

        ObjectMapper mapper = new ObjectMapper();
        // 将入参JSON序列化
        String jsonParam = mapper.writeValueAsString(joinPoint.getArgs());
        // 将返回结果JSON序列化
        String jsonResult = null;
        if (proceed != null) {
            jsonResult = mapper.writeValueAsString(proceed);
        }

        log.info("exec info\ntarget:{}.{}\nexecution:{}ms\nparameter:{}\nresult:{}"
                , joinPoint.getTarget().getClass().getSimpleName()
                , joinPoint.getSignature().getName()
                ,(et - st)
                , jsonParam
                , jsonResult
        );
        return proceed;
    }
}

测试

@RestController
@RequestMapping("home")
public class HomeController {

    @MethodExporter
    @GetMapping
    public String index(){
        ThreadUtil.sleep(2000);
        return RandomUtil.randomString(10);
    }
}

结果

2023-03-26 15:53:10.183  INFO 9452 --- [nio-8080-exec-1] c.y.s.aspect.MethodExporterAspect        : exec info
target:HomeController.index
execution:2011ms
parameter:[]
result:"rx3w1hengr"

标签:java,String,Greeting,代理,AOP,import,public,greeting
From: https://www.cnblogs.com/dylmys/p/17258746.html

相关文章

  • Spring AOP 和 AspectJ AOP 有什么区别?
    什么是AOPAOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-OrientedPrograming,面向对象编程)的补充和完善。AOP技它利用一种称为“横切”的技术,剖解开封装的......
  • 设计模式-用代理模式(Proxy Pattern)来拯救你的代码:打造可靠的程序设计
    前言设计模式是一种高级编程技巧,也是一种通用的解决方案。它能在不同的应用场景中使用,它可以提高代码的可读性、可复用性和可维护性。设计模式的学习能提高我们的编程能力......
  • Spring AOP有哪些通知类型,它们的执行顺序是怎样的?
    通知类型在基于SpringAOP编程的过程中,基于AspectJ框架标准,spring中定义了五种类型的通知,它们分别是:前置通知(@Before)。返回通知(@AfterReturning)。异常通......
  • Python程序使用代理
    包括jupyter以内的python程序使用代理添加一下代码:#导入模块importos#设置代理proxy='http://127.0.0.1:1080'#代理地址os.environ['http_proxy']=proxyos......
  • DataOps是什么
    1►DataOps到底是什么?伴随着全球数字化转型的高速发展,在云计算、物联网、5G、边缘计算、元宇宙等新技术的驱动下,数据爆炸的时代已经来临。IDCGlobalDataSphere显示,2021......
  • 结构型-代理模式
    定义  代理是一个中间者的角色,如生活中的中介,出于种种考虑/限制,一个对象不能直接访问另一个对象,需要一个第三者(中间代理)牵线搭桥从而间接达到访问目的,这样的就是代理......
  • 代理模式
    一、作用代理模式,也称为委托模式,作用就是找一个对象来替我们访问某个对象;意图:为其它对象提供一种代理以控制对这个对象的访问;代理模式就像我们生活中有些不方便自己直接出......
  • 动态代理
    动态代理思想的分析我们想在已经可以运行的代码中添加右侧的2行代码在种情况下如果我们直接修改,被称为侵入式修改,很可能和导致我们的所以代码都崩溃我们又不能修改原......
  • jdk的动态代理
    jdk动态代理:(jdk动态代理,必须有接口)1-Calculator接口内容:publicinterfaceCalculator{intadd(inti,intj);intsub(inti,intj);intmul(inti,......
  • 在同一网络下手机通过代理服务连接电脑的socks
    让手机和电脑连接同一WiFi,查看电脑的IP地址。此为192.168.1.100ipconfig2.打开电脑的socks,并查看端口,此端口为108083.打开手机WIFI连接,选择高级设置,点击代理,选择......