【小家Spring】Spring Framework提供的实用纯Java工具类大合集(二)(中)

简介: 【小家Spring】Spring Framework提供的实用纯Java工具类大合集(二)(中)

demo show:


    public static void main(String[] args) {
        //String filePath = "links\\fsx\\A.class";
        String filePath = "links/fsx/A.class";
        System.out.println(ClassUtils.convertResourcePathToClassName(filePath)); //links.fsx.A.class
        //System.out.println(ClassUtils.convertClassNameToResourcePath(filePath));
        //在指定类的所属包下面,寻找一个资源文件,并返回该资源文件的文件路径 java.lang.String
        System.out.println(ClassUtils.addResourcePathToPackagePath(String.class, "someResource.xml")); // java/lang/someResource.xml
        System.out.println(ClassUtils.classPackageAsResourcePath(String.class)); //java/lang
        // 打印classNames
        System.out.println(ClassUtils.classNamesToString(String.class, Integer.class)); //[java.lang.String, java.lang.Integer]
        System.out.println(ClassUtils.classNamesToString(Arrays.asList(String.class, Integer.class))); //[java.lang.String, java.lang.Integer]
    }


    public static void main(String[] args) {
        //String filePath = "links\\fsx\\A.class";
        String filePath = "links/fsx/A.class";
        System.out.println(ClassUtils.convertResourcePathToClassName(filePath)); //links.fsx.A.class
        //System.out.println(ClassUtils.convertClassNameToResourcePath(filePath));
        //在指定类的所属包下面,寻找一个资源文件,并返回该资源文件的文件路径 java.lang.String
        System.out.println(ClassUtils.addResourcePathToPackagePath(String.class, "someResource.xml")); // java/lang/someResource.xml
        System.out.println(ClassUtils.classPackageAsResourcePath(String.class)); //java/lang
        // 打印classNames
        System.out.println(ClassUtils.classNamesToString(String.class, Integer.class)); //[java.lang.String, java.lang.Integer]
        System.out.println(ClassUtils.classNamesToString(Arrays.asList(String.class, Integer.class))); //[java.lang.String, java.lang.Integer]
    }


Demo:

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        // 拿到该实例实现的所有的接口
        System.out.println(Arrays.asList(ClassUtils.getAllInterfaces(list))); //[interface java.util.List, interface java.util.RandomAccess, interface java.lang.Cloneable, interface java.io.Serializable, interface java.util.Collection]
        System.out.println(ClassUtils.getAllInterfacesAsSet(list)); // 输出结果同上
    }


  // 这个方法很有意思:找到两个Class 的祖先类(也就是谁是父类就返回谁了)
  public static Class<?> determineCommonAncestor(@Nullable Class<?> clazz1, @Nullable Class<?> clazz2) {}

这个方法很有意思,Spring在Autowired自动注入AbstractAutowireCapableBeanFactory中有大量的应用:


    public static void main(String[] args) {
        System.out.println(ClassUtils.determineCommonAncestor(Integer.class,Long.class)); //class java.lang.Number  找到他们共同父类
        System.out.println(ClassUtils.determineCommonAncestor(Integer.class,Number.class)); //class java.lang.Number  若其中一个就是父类 就直接返回即可
        System.out.println(ClassUtils.determineCommonAncestor(Integer.class, Person.class)); //null  八竿子打不着就返回null吧(注意相当于是Object.class 直接返回null的)
    }


  // 是否是内部类
  public static boolean isInnerClass(Class<?> clazz) {
    return (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers()));
  }
  // 是否是CGLIB代理对象
  public static boolean isCglibProxy(Object object) {
    return isCglibProxyClass(object.getClass());
  }
  public static boolean isCglibProxyClass(@Nullable Class<?> clazz) {
    return (clazz != null && isCglibProxyClassName(clazz.getName()));
  }
  public static boolean isCglibProxyClassName(@Nullable String className) {
    return (className != null && className.contains(CGLIB_CLASS_SEPARATOR));
  }
  // 获取用户定义的本来的类型,大部分情况下就是类型本身,主要针对cglib做了额外的判断,获取cglib代理之后的父类;
  public static Class<?> getUserClass(Object instance) {}
  // 获取一个对象的描述类型;一般来说,就是类名,能够正确处理数组,如果是JDK代理对象,能够正确输出其接口类型:
  public static String getDescriptiveType(@Nullable Object value) { ... }
  public static String getShortName(String className) {
  public static String getShortName(Class<?> clazz) {
  public static String getShortNameAsProperty(Class<?> clazz) {
  public static String getClassFileName(Class<?> clazz) {
  public static String getPackageName(Class<?> clazz) {
  public static String getPackageName(String fqClassName) {
  public static String getQualifiedName(Class<?> clazz) {

Demo show:


     public static void main(String[] args) {
        System.out.println(ClassUtils.getShortName("java.lang.String")); //String
        System.out.println(ClassUtils.getShortName(String.class)); //String
        System.out.println(ClassUtils.getShortNameAsProperty(String.class)); //String
        System.out.println(ClassUtils.getPackageName(String.class)); //java.lang
        System.out.println(ClassUtils.getPackageName("java.lang.String")); //java.lang
        // clazz.getTypeName()
        System.out.println(ClassUtils.getQualifiedName(String.class)); //java.lang.String
        System.out.println(String.class.getName()); //java.lang.String
        System.out.println(String.class.getTypeName()); //java.lang.String
        System.out.println(ClassUtils.getDescriptiveType(ArrayList.class)); //java.lang.Class  注意此处的输出
        java.lang.Class
        //System.out.println(ClassUtils.getDescriptiveType(getClass()));
        java.lang.String[]
        //System.out.println(ClassUtils.getDescriptiveType(new String[]{}));
        //
        com.sun.proxy.$Proxy20 implementing cn.wolfcode.springboot.utilstest.IEmployeeService,
        cn.wolfcode.springboot.utilstest.IAddition,
        org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised
        //System.out.println(ClassUtils.getDescriptiveType(service));
    }
}


  public static String getQualifiedMethodName(Method method) {
  public static String getQualifiedMethodName(Method method, @Nullable Class<?> clazz) {
  public static boolean hasConstructor(Class<?> clazz, Class<?>... paramTypes) {
  public static <T> Constructor<T> getConstructorIfAvailable(Class<T> clazz, Class<?>... paramTypes) {
  //判断类是否有指定的public方法
  public static boolean hasMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
  public static Method getMethod(Class<?> clazz, String methodName, @Nullable Class<?>... paramTypes) {
  public static Method getMethodIfAvailable(Class<?> clazz, String methodName, @Nullable Class<?>... paramTypes) {
  //获取指定类中匹配该方法名称的方法个数,包括非public方法;
  public static int getMethodCountForName(Class<?> clazz, String methodName) {
  //判定指定的类及其父类中是否包含指定方法名称的方法,包括非public方法;
  public static boolean hasAtLeastOneMethodWithName(Class<?> clazz, String methodName) {
  //获得最匹配的一个可以执行的方法; 和Overrid有关
  public static Method getMostSpecificMethod(Method method, @Nullable Class<?> targetClass) {
  //该方法用于判定一个方法是否是用户可用的方法
  public static boolean isUserLevelMethod(Method method) {
    // 桥接方法,
    // method. isSynthetic方法:判定一个方法是否是虚构方法(synthetic method);什么是synthetic方法?由编译器创建的,非默认构造方法
    //(我们知道,类都有默认构造方法,当然重载了默认构造方法的除外,编译器都会生成一个默认构造方法的实现)在源码中没有对应的方法实现的方法都是虚构方法。
    // 比如上面介绍的bridge方法就是一个典型的synthetic方法;
    // isGroovyObjectMethod:判定一个方法是否是Groovy的方法,因为Spring支持Groovy,而Groovy的类都实现了groovy.lang.GroovyObject类;
    return (method.isBridge() || (!method.isSynthetic() && !isGroovyObjectMethod(method)));
  }
  public static Method getStaticMethod(Class<?> clazz, String methodName, Class<?>... args) {


很多方法依赖于ReflectionUtils,建议使用它吧


Introspector:内省


反射:反射就是让你可以通过名称来得到对象(类,属性,方法)的技术。例如我们可以通过类名来生成一个类的实例;知道了方法名,就可以调用这个方法;知道了属性名就可以访问这个属性的值

内省:内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。所以它是位于Bean包下的:java.beans.Introspector,它有个方法BeanInfo bi = Introspector.getBeanInfo(demo.getClass(),Object.class);就能获取到一个BeanInfo,从而获取到每个属性值。


Struts将表单数据映射到JavaBean就是通过内省来实现的


这里面推荐两篇文章:

内省(一)之Introspector、BeanInfo、PropertyDescriptor

内省(二)之BeanUtils工具类


MethodIntrospector


// @since 4.2.3
// 定义彻底搜索元数据关联方法的算法,包括接口和父类,同时还处理参数化方法,以及接口和基于类的代理遇到的常见场景
// 通常,但不一定,用于查找带注释的处理程序方法~~~~~~~~~~~~~~
// 也就是说倘若你的注解啥的,在接口上也是可以的
public abstract class MethodIntrospector {
  // 核心方法:就是从指定的targetType里找到合适的方法。metadataLookup:用于过滤
  public static <T> Map<Method, T> selectMethods(Class<?> targetType, final MetadataLookup<T> metadataLookup) {
    final Map<Method, T> methodMap = new LinkedHashMap<>();
    Set<Class<?>> handlerTypes = new LinkedHashSet<>();
    Class<?> specificHandlerType = null;
    // 如果该类型 不是JDK动态代理类型
    if (!Proxy.isProxyClass(targetType)) {
      specificHandlerType = ClassUtils.getUserClass(targetType);
      handlerTypes.add(specificHandlerType);
    }
    // 拿到该目标类型所有的实现的接口们~~~~~~~
    handlerTypes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetType));
    // 遍历所有的需要处理的handlerTypes  然后一个个的处理
    for (Class<?> currentHandlerType : handlerTypes) {
      // 如果找到了specificHandlerType ,那就用它,否则就是currentHandlerType
      final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
      // 使用的是ReflectionUtils.USER_DECLARED_METHODS 方法过滤器。
      ReflectionUtils.doWithMethods(currentHandlerType, method -> {
        Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
        // 对这个specificMethod 还会做进一步的处理~~~~
        T result = metadataLookup.inspect(specificMethod);
        if (result != null) {
          Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
          //==================================
          if (bridgedMethod == specificMethod || metadataLookup.inspect(bridgedMethod) == null) {
            methodMap.put(specificMethod, result);
          }
        }
      }, ReflectionUtils.USER_DECLARED_METHODS);
    }
    return methodMap;
  }
  public static Set<Method> selectMethods(Class<?> targetType, final ReflectionUtils.MethodFilter methodFilter) {
    return selectMethods(targetType,
        (MetadataLookup<Boolean>) method -> (methodFilter.matches(method) ? Boolean.TRUE : null)).keySet();
  }
  public static Method selectInvocableMethod(Method method, Class<?> targetType) {
    if (method.getDeclaringClass().isAssignableFrom(targetType)) {
      return method;
    }
    try {
      String methodName = method.getName();
      Class<?>[] parameterTypes = method.getParameterTypes();
      for (Class<?> ifc : targetType.getInterfaces()) {
        try {
          return ifc.getMethod(methodName, parameterTypes);
        }
        catch (NoSuchMethodException ex) {
          // Alright, not on this interface then...
        }
      }
      // A final desperate attempt on the proxy class itself...
      return targetType.getMethod(methodName, parameterTypes);
    }
    catch (NoSuchMethodException ex) {
      throw new IllegalStateException(String.format(
          "Need to invoke method '%s' declared on target class '%s', " +
          "but not found in any interface(s) of the exposed proxy type. " +
          "Either pull the method up to an interface or switch to CGLIB " +
          "proxies by enforcing proxy-target-class mode in your configuration.",
          method.getName(), method.getDeclaringClass().getSimpleName()));
    }
  }
  @FunctionalInterface
  public interface MetadataLookup<T> {
    @Nullable
    T inspect(Method method);
  }
}


它的使用还是非常多得:


image.png

示例代码:


// 处理@EventListener注解
annotatedMethods = MethodIntrospector.selectMethods(targetType, 
  (MethodIntrospector.MetadataLookup<EventListener>) method -> AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
// 处理@Scheduled和@Schedules注解
Map<Method, Set<Scheduled>> annotatedMethods = MethodIntrospector.selectMethods(targetClass,
  (MethodIntrospector.MetadataLookup<Set<Scheduled>>) method -> {
    Set<Scheduled> scheduledMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations(method, Scheduled.class, Schedules.class);



相关文章
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
114 2
|
18天前
|
Java Spring
Java Spring Boot监听事件和处理事件
通过上述步骤,我们可以在Java Spring Boot应用中实现事件的发布和监听。事件驱动模型可以帮助我们实现组件间的松耦合,提升系统的可维护性和可扩展性。无论是处理业务逻辑还是系统事件,Spring Boot的事件机制都提供了强大的支持和灵活性。希望本文能为您的开发工作提供实用的指导和帮助。
69 15
|
16天前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
|
1月前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
83 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
2月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
276 12
基于开源框架Spring AI Alibaba快速构建Java应用
|
3月前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
3月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
172 2
|
2月前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
67 0
|
2月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
55 0
|
缓存 Java 测试技术
Spring Framework发布5.3.11和5.2.18
Spring Framework发布5.3.11和5.2.18
402 0