• Spring的@DeclareParents注解


    介绍

    作用: 
      用于给被增强的类提供新的方法。(实现新的接口)
    属性:
      value:
        用于指定目标类型的表达式。当在全限定类名后面跟上+时,表示当前类
    及其子类
      defaultImpl:
          指定提供方法或者字段的默认实现类。
    使用场景:
      当我们已经完成了一个项目的某个阶段开发,此时需要对已完成的某个类加入一些新的方法,我们首先想到的是写一个接口,然后让这些需要方法的类实现此接口,但是如果目标类非常复杂,牵一发而动全身,改动的话可能非常麻烦。此时就可以使用此注解,然后建一个代理类,同时代理该类和目标类。
    

    简介(在 AspectJ 中称为类型间声明)使方面可以声明建议对象实现给定的接口,并代表那些对象提供该接口的实现。

    您可以使用@DeclareParentsComments 进行介绍。此注解用于声明匹配类型具有新的父代(因此而得名)。例如,在给定名为UsageTracked的接口和该接口名为DefaultUsageTracked的实现的情况下,以下方面声明服务接口的所有实现者也都实现UsageTracked接口(例如,通过 JMX 公开统计信息):

    @Aspect
    public class UsageTracking {
    
        @DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
        public static UsageTracked mixin;
    
        @Before("com.xyz.myapp.SystemArchitecture.businessService() && this(usageTracked)")
        public void recordUsage(UsageTracked usageTracked) {
            usageTracked.incrementUseCount();
        }
    
    }
    

    要实现的接口由带 Comments 的字段的类型确定。 @DeclareParents注解的value属性是 AspectJ 类型的模式。任何匹配类型的 bean 都实现UsageTracked接口。请注意,在前面示例的建议中,服务 Bean 可以直接用作UsageTracked接口的实现。如果以编程方式访问 bean,则应编写以下内容:

    UsageTracked usageTracked = (UsageTracked) context.getBean("myService");
    

    示例代码

    /**
     * @author WGR
     * @create 2020/9/23 -- 13:33
     */
    public class ValidateServiceImpl implements ValidateService {
        @Override
        public boolean checkUser(User user) {
            if(user.getNickname().contains("孙子")){
                    return false;
              }
               return true;
        }
    }
    
    /**
     * @author WGR
     * @create 2020/9/23 -- 13:32
     */
    public interface ValidateService {
    
        boolean checkUser(User user);
    }
    
    @Component
    @Aspect//表明当前类是一个切面类
    public class LogUtil {
    
        @DeclareParents(value = "com.dalianpai.spring5.aop.service.UserService+", defaultImpl = ValidateServiceImpl.class)
        public static ValidateService validateService;
    
        @Before(value = "execution(* com.dalianpai.spring5.aop.service.impl.*.*(..)) && args(user,id) && this(validateService)")
        public void beforePrintLogC(String id, User user, ValidateService validateService) {
            boolean check = validateService.checkUser(user);
            if (check) {
                System.out.println("执行打印日志的功能");
            } else {
                throw new IllegalStateException("名称非法");
            }
            System.out.println("前置通知增强了beforePrintLoga" + id + "," + user);
        }
    
    
    }
    
    

    image-20200923135111176

  • 相关阅读:
    剑指offer系列——56.删除链表中重复的结点
    剑指offer系列——55.链表中环的入口结点
    剑指offer系列——54.字符流中第一个不重复的字符
    剑指offer系列——53.表示数值的字符串
    MinGW与Cygwin
    Android-x86虚拟机安装配置全攻略
    linux下使用NFS挂载文件系统
    ubuntu 64bit “arm-linux-gcc: No such file or directory”问题的解决方法
    虚拟机下ubuntu的minicom使用指南
    Linux 下编译、安装、配置 QT
  • 原文地址:https://www.cnblogs.com/dalianpai/p/13717912.html
Copyright © 2020-2023  润新知