首页 > 其他分享 >Solon2 开发之容器,七、切面与函数环绕拦截

Solon2 开发之容器,七、切面与函数环绕拦截

时间:2023-02-12 22:12:34浏览次数:34  
标签:容器 Logging inv class 切面 Solon2 rst 拦截 public

想要环绕拦截一个 Bean 的函数。需要三个前置条件:

  1. 通过注解做为“切点”,进行拦截(不能无缘无故给拦了吧?费性能)
  2. Bean 的 method 是被代理的
  3. 在 Bean 被扫描之前,完成环绕拦截的注册

1、定义切点和注册环绕拦截

Solon 的切点,通过注解实现,得先定义一个。例如:@Logging

//@Target 是决定可以注在什么上面的
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Logging {
    boolean enable() default true;
}

定义拦截器

//简单点处理
@Slf4j
public class LoggingInterceptor implements Interceptor {
    @Override
    public Object doIntercept(Invocation inv) throws Throwable {
        //此处为拦截处理
        Object rst = inv.invoke();

        log.info("Args: {}\nReturn: {}", inv.args(), rst);

        return rst;
    }
}

//如果需要取注解信息,并进行控制
@Slf4j
public class LoggingInterceptor2 implements Interceptor {
    @Override
    public Object doIntercept(Invocation inv) throws Throwable {
        Logging anno = inv.method().getAnnotation(Logging.class);

        if (anno == null) {
            //因为 Logging 支持 ElementType.TYPE,所以也要检查类上的注解
            anno = inv.target().getClass().getAnnotation(Logging.class);
        }
        
        //此处为拦截处理
        Object rst = inv.invoke();

        if(anno != null && anno.enable()){
            log.info("Args: {}\nReturn: {}", inv.args(), rst);
        }

        return rst;
    }
}

手动注册或关联绑定环绕拦截(二种模式,选一即可)

//手动注册模式
Solon.context().beanAroundAdd(Logging.class, new LoggingInterceptor());

//关联绑定模式(通过@Around注解,直接在注解类上关联绑定)
@Around(LoggingInterceptor.class)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Logging {
}

现在切点定义好了,可以到处“埋”了...

2、应用:把切点“埋”到需要的地方

@Service
public class DemoController{
    @Logging
    public void addUser(UserModel user){
        //...
    }
}

就这样完成一个面向切面的开发了。

3、通过插件及插件配置,变成一个复用的东西

这是刚才定义注解:

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

开发插件:

@Slf4j
public class XPluginImp implements Plugin {
    @Override
    public void start(AopContext context) {
        context.beanAroundAdd(Logging.class, inv->{
            Object rst = inv.invoke();

            log.info("Args: {}\nReturn: {}", inv.args(), rst);
        });
    }
}

配置插件:

solon.plugin=xxx.xxx.log.XPluginImp

一个可复用的插件开发完成了。关于Solon插件开发,可参考别的章节内容。

标签:容器,Logging,inv,class,切面,Solon2,rst,拦截,public
From: https://www.cnblogs.com/noear/p/17114838.html

相关文章

  • Solon2 开发之容器,八、动态代理的本质
    在Java里动态代理,主要分:接口动态代理和类动态代理。因为它的代理类都是动态创建的,所以名字里会带上“动态”。官网的有些地方叫“代理”,也有些地方叫“动态代理”。都......
  • WPF学习笔记(窗体和常用容器的使用)
    WPF学习笔记(窗体和常用容器的使用)新手学习之路;望大佬们指点迷津目录WPF学习笔记(窗体和常用容器的使用)窗体(Window)常用属性:圆角无边框窗体设置及效果展示Grid基本属......
  • Solon2 开发之容器,三、注入或手动获取 Bean
    1、如何注入Bean?先了解一下Bean生命周期的简化版:运行构建函数尝试字段注入(有时同步注入,没时订阅注入。不会有相互依赖而卡住的问题)@Init函数(是在容器初始化完成后才......
  • Solon2 开发之容器,四、注入依赖与初始化
    Solon强调有克制的注入+手动控制结合的模式。好处是,代码用料少、启动快。Bean的关键生命节点:节点说明1.Constructor(构造方法)不支持参数注入2.@In......
  • Solon2 开发之容器,一、注入或手动获取配置
    约定resources/app.yml(或app.properties)#为应用配置文件配置样例track:name:xxxurl:http://a.a.adb1:jdbcUrl:"jdbc:mysql://..."username:......
  • Solon2 开发之容器,二、构建一个 Bean 的三种方式
    1、手动简单的构建://生成普通的BeanSolon.context().wrapAndPut(UserService.class,newUserServiceImpl());//生成带注解的Bean(比如:@Controller)Solon.context().be......
  • 容器部署分布式zabbix
    之前有写过docker-compose部署zabbix的博客这里再总结下分布式部署zabbix的笔记,这里重点是部署zabbix-proxy同样需要准备数据库配置文件数据库配置文件差不多这里是doc......
  • Docker consul的容器服务更新与发现
    一、Consul概述(1)什么是服务注册与发现服务注册与发现是微服务架构中不可或缺的重要组件。起初服务都是单节点的,不保障高可用性,也不考虑服务的压力承载,服务之间调用单纯的......
  • #yyds干货盘点# LeetCode面试题:盛最多水的容器
    1.简述:给定一个长度为n的整数数组 height 。有 n 条垂线,第i条线的两个端点是 (i,0) 和 (i,height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可......
  • 【Docker】MySQL容器定时备份
    我们通常使用原生的mysql会比较多,mysql的备份也耳熟能详。假如现在有个mysql数据库username为root,password为123456,且现在要导出schema为db1、db2的数据。在本地导出的时候......