Большинство наших проектов основаны на архитектуре Spring.Сам Spring содержит много полезных классов инструментов.Обучение использованию этих классов инструментов не только позволяет нам добиться вдвое большего результата с половиной усилий,но и сокращает введение ненужных дополнительных классов инструментов . При просмотре исходного кода этих классов инструментов обнаруживается, что все они являются абстрактными типами, потому что методы классов инструментов обычно являются статическими статическими методами, статическими методами и привязками классов, которые можно использовать после загрузки класса без создания экземпляра. (просто абстрактный. Классы не могут быть созданы напрямую и могут определять неабстрактные методы), поэтому более уместно определить служебный класс как абстрактный.
Метод печати в этой статье является инкапсуляцией System.out.println:
private static void print(Object value) {
System.out.println(value);
}
ClassUtils
org.springframework.util.classUtils
содержит некоторые иjava.lang.Class
Связанные служебные методы.
getDefaultClassLoader
ClassLoader getDefaultClassLoader()
Получите загрузчик классов текущего контекста потока:
print(ClassUtils.getDefaultClassLoader());
sun.misc.Launcher$AppClassLoader@18b4aac2
overrideThreadContextClassLoader
ClassLoader overrideThreadContextClassLoader(@Nullable ClassLoader classLoaderToUse)
Переопределите загрузчик классов текущего контекста потока с помощью определенного загрузчика классов:
print(ClassUtils.getDefaultClassLoader());
ClassUtils.overrideThreadContextClassLoader(ClassLoader.getSystemClassLoader().getParent());
print(ClassUtils.getDefaultClassLoader());
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@3feba861
forName
forName(String name, @Nullable ClassLoader classLoader)
Возвращает экземпляр класса по имени класса, аналогично Class.forName(), но более мощное и может использоваться для примитивных типов, внутренних классов и т. д.:
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
print(ClassUtils.forName("int", classLoader));
print(ClassUtils.forName("java.lang.String[]", classLoader));
print(ClassUtils.forName("java.lang.Thread$State", classLoader));
int
class [Ljava.lang.String;
class java.lang.Thread$State
isPresent
boolean isPresent(String className, @Nullable ClassLoader classLoader)
Определите, содержит ли текущий classLoader целевой тип (включая все его родительские классы и интерфейсы):
ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
print(ClassUtils.isPresent("int", classLoader));
print(ClassUtils.isPresent("intt", classLoader));
true
false
resolvePrimitiveClassName
Class<?> resolvePrimitiveClassName(@Nullable String name)
Получить исходный класс по заданному имени класса:
print(ClassUtils.resolvePrimitiveClassName("int"));
print(ClassUtils.resolvePrimitiveClassName("java.lang.Integer"));
int
null
isPrimitiveWrapper
boolean isPrimitiveWrapper(Class<?> clazz)
Определите, является ли данный класс классом-оболочкой, таким как Boolean, Byte, Character, Short, Integer, Long, Float, Double или Void:
print(ClassUtils.isPrimitiveWrapper(Integer.class));
print(ClassUtils.isPrimitiveWrapper(Character.class));
print(ClassUtils.isPrimitiveWrapper(Void.class));
print(ClassUtils.isPrimitiveWrapper(String.class));
true
true
true
false
Аналогичные методы такжеisPrimitiveOrWrapper
Определите, является ли это примитивным классом или классом-оболочкой,isPrimitiveWrapperArray
Определите, является ли это массивом классов-оболочек,isPrimitiveArray
Определяет, является ли массив примитивным классом.
resolvePrimitiveIfNecessary
Class<?> resolvePrimitiveIfNecessary(Class<?> clazz)
Если данный класс является исходным классом, верните соответствующий класс-оболочку, в противном случае верните данный класс напрямую:
print(ClassUtils.resolvePrimitiveIfNecessary(int.class));
print(ClassUtils.resolvePrimitiveIfNecessary(Object.class));
class java.lang.Integer
class java.lang.Object
isAssignable
boolean isAssignable(Class<?> lhsType, Class<?> rhsType)
Проверьте, может ли rhsType быть назначен lhsType путем отражения (обратите внимание, что тип оболочки может быть назначен соответствующему примитивному типу, механизм автоматической распаковки):
print(ClassUtils.isAssignable(Integer.class, int.class));
print(ClassUtils.isAssignable(Object.class, String.class));
print(ClassUtils.isAssignable(BeanPostProcessor.class, InstantiationAwareBeanPostProcessor.class));
print(ClassUtils.isAssignable(double.class, Double.class)); // consider this
print(ClassUtils.isAssignable(Integer.class, Long.class));
true
true
true
true
false
isAssignableValue
boolean isAssignableValue(Class<?> type, @Nullable Object value)
Проверьте, соответствует ли данное значение заданному типу:
print(ClassUtils.isAssignableValue(Integer.class, 1));
print(ClassUtils.isAssignableValue(Integer.class, 1L));
print(ClassUtils.isAssignableValue(int.class, Integer.valueOf(1)));
print(ClassUtils.isAssignableValue(Object.class,1));
print(ClassUtils.isAssignableValue(String.class,1));
true
false
true
true
false
convertResourcePathToClassName
String convertResourcePathToClassName(String resourcePath)
Преобразуйте путь к классам в полное имя класса:
print(ClassUtils.convertResourcePathToClassName("java/lang/String"));
java.lang.String
на самом деле/
заменить.
.convertClassNameToResourcePath
Метод работает наоборот.
classNamesToString
String classNamesToString(Class<?>... classes)
Посмотрите прямо на демо без объяснений:
print(ClassUtils.classNamesToString(String.class, Integer.class, BeanPostProcessor.class));
[java.lang.String, java.lang.Integer, org.springframework.beans.factory.config.BeanPostProcessor]
getAllInterfaces
Class<?>[] getAllInterfaces(Object instance)
Возвращает набор типов интерфейса, реализованных данным объектом экземпляра:
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
Class<?>[] allInterfaces = ClassUtils.getAllInterfaces(processor);
Arrays.stream(allInterfaces).forEach(System.out::println);
interface org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor
interface org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor
interface org.springframework.core.PriorityOrdered
interface org.springframework.beans.factory.BeanFactoryAware
Аналогичные методы такжеgetAllInterfacesForClass
,getAllInterfacesAsSet
,getAllInterfacesForClassAsSet
determineCommonAncestor
Class<?> determineCommonAncestor(@Nullable Class<?> clazz1, @Nullable Class<?> clazz2)
Найдите общего предка данного типа (так называемый общий предок относится к данному типу, вызывающемуclass.getSuperclass
Полученный общий тип, если заданный тип Object.class, interface, примитивный тип или Void, возвращает null напрямую):
// 它两都是接口
print(ClassUtils.determineCommonAncestor(AutowireCapableBeanFactory.class, ListableBeanFactory.class));
print(ClassUtils.determineCommonAncestor(Long.class, Integer.class));
print(ClassUtils.determineCommonAncestor(String.class, Integer.class));
null
class java.lang.Number
null
isInnerClass
boolean isInnerClass(Class<?> clazz)
Определите, является ли данный тип внутренним классом (нестатическим):
class A {
class B {
}
}
print(ClassUtils.isInnerClass(A.B.class)); // true
static class A {
class B {
}
}
print(ClassUtils.isInnerClass(A.B.class)); // true
static class A {
static class B {
}
}
print(ClassUtils.isInnerClass(A.B.class)); // false
isCglibProxy
boolean isCglibProxy(Object object)
Это прокси-объект Cglib:
@SpringBootApplication
public class AopApplication {
@Configuration
static class MyConfigure {
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(AopApplication.class, args);
MyConfigure myConfigure = context.getBean(MyConfigure.class);
System.out.println(ClassUtils.isCglibProxy(myConfigure));
}
}
true
Возвращает false, если класс конфигурации не проксируется Cglib:
@SpringBootApplication
public class AopApplication {
@Configuration(proxyBeanMethods = false) // 注意这里
static class MyConfigure {
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(AopApplication.class, args);
MyConfigure myConfigure = context.getBean(MyConfigure.class);
System.out.println(ClassUtils.isCglibProxy(myConfigure));
}
}
false
Однако этот метод устарел, рекомендуется использоватьorg.springframework.aop.support.AopUtils.isCglibProxy(Object)
метод.
getUserClass
Class<?> getUserClass(Object instance)
Возвращает тип, соответствующий данному экземпляру.Если экземпляр является прокси-объектом Cglib, он возвращает тип целевого прокси-объекта:
print(ClassUtils.getUserClass("Hello")); // class java.lang.String
Пример прокси Cglib:
@SpringBootApplication
public class AopApplication {
@Configuration
static class MyConfigure {
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(AopApplication.class, args);
MyConfigure myConfigure = context.getBean(MyConfigure.class);
// 注意它们的区别
System.out.println(myConfigure.getClass());
System.out.println(ClassUtils.getUserClass(myConfigure));
}
}
class cc.mrbird.aop.AopApplication$MyConfigure$$EnhancerBySpringCGLIB$$e51ce45
class cc.mrbird.aop.AopApplication$MyConfigure
matchesTypeName
boolean matchesTypeName(Class<?> clazz, @Nullable String typeName)
Проверьте, совпадают ли заданные имена классов и типов:
print(ClassUtils.matchesTypeName(String.class, "java.lang.String")); // true
getShortName
String getShortName(Class<?> clazz)
Вернуть имя класса:
print(ClassUtils.getShortName(String.class)); // String
getShortNameAsProperty
String getShortNameAsProperty(Class<?> clazz)
Верните имя класса с первой строчной буквой, если это внутренний класс, удалите имя внешнего класса:
print(ClassUtils.getShortNameAsProperty(String.class)); // string
class A {
class B {
}
}
print(ClassUtils.getShortNameAsProperty(String.class)); // b
getClassFileName
String getClassFileName(Class<?> clazz)
Вернуть имя класса + .class:
print(ClassUtils.getShortNameAsProperty(String.class)); // String.class
getPackageName
String getPackageName(Class<?> clazz)
Имя возвращаемого пакета:
print(ClassUtils.getShortNameAsProperty(String.class)); // java.lang
getQualifiedName
String getQualifiedName(Class<?> clazz)
Возвращает полное имя класса с [] в конце, если это тип массива:
print(ClassUtils.getQualifiedName(String.class));
print(ClassUtils.getQualifiedName(String[].class));
java.lang.String
java.lang.String[]
getQualifiedMethodName
String getQualifiedMethodName(Method method)
Получите полное имя метода:
print(ClassUtils.getQualifiedMethodName(
ClassUtils.class.getDeclaredMethod("getQualifiedMethodName", Method.class
)));
org.springframework.util.ClassUtils.getQualifiedMethodName
hasConstructor
boolean hasConstructor(Class<?> clazz, Class<?>... paramTypes)
Проверьте, есть ли у данного типа конструктор с заданным параметром типа:
print(ClassUtils.hasConstructor(String.class, String.class));
print(ClassUtils.hasConstructor(String.class, Object.class));
true
false
getConstructorIfAvailable
<T> Constructor<T> getConstructorIfAvailable(Class<T> clazz, Class<?>... paramTypes)
Возвращает конструктор данного типа параметра для данного типа или null, если нет:
Constructor<String> constructorIfAvailable = ClassUtils.getConstructorIfAvailable(String.class, String.class);
print(constructorIfAvailable != null);
print(constructorIfAvailable.toString());
true
public java.lang.String(java.lang.String)
hasMethod
boolean hasMethod(Class<?> clazz, Method method)
Проверьте, имеет ли данный тип указанный метод:
Method hasMethod = ClassUtils.class.getDeclaredMethod("hasMethod", Class.class, Method.class);
print(ClassUtils.hasMethod(ClassUtils.class, hasMethod)); // true
перегруженный методboolean hasMethod(Class<?> clazz, String methodName, Class<?>... paramTypes)
.
getMethod
Method getMethod(Class<?> clazz, String methodName, @Nullable Class<?>... paramTypes)
Найдите указанный метод из указанного типа и создайте исключение IllegalStateException, если он не найден:
ClassUtils.getMethod(ClassUtils.class,"hello", String.class);
java.lang.IllegalStateException: Expected method not found: java.lang.NoSuchMethodException: org.springframework.util.ClassUtils.hello(java.lang.String)
Если вы хотите вернуть null вместо того, чтобы генерировать исключение, если оно не найдено, вы можете использоватьgetMethodIfAvailable
метод.
getMethodCountForName
int getMethodCountForName(Class<?> clazz, String methodName)
Найдите количество методов указанного типа по имени метода (учитываются переопределение, перегрузка и непубличность):
print(ClassUtils.getMethodCountForName(ClassUtils.class,"hasMethod")); // 2
Аналогичные методы такжеhasAtLeastOneMethodWithName
, должен быть хотя бы один.
getStaticMethod
Method getStaticMethod(Class<?> clazz, String methodName, Class<?>... args)
Получить статический метод заданного типа или null, если метод не статический или такого метода нет:
Method method = ClassUtils.getStaticMethod(ClassUtils.class, "getDefaultClassLoader");
print(method != null);
print(method.getReturnType());
true
class java.lang.ClassLoader
FileSystemUtils
Служебный класс файловой системы
deleteRecursively
boolean deleteRecursively(@Nullable File root)
Рекурсивно удаляет указанный файл или каталог, возвращает true, если удаление прошло успешно, и false, если не удалось, и исключение не выдается.
Каталог удаления утилиты File пытается удалить каталог a:
File file = new File("a");
print(file.delete()); // false
Поскольку каталог a содержит подкаталоги (файлы), следует использовать рекурсивное удаление:
File file = new File("a");
print(FileSystemUtils.deleteRecursively(file)); // true
перегруженный методboolean deleteRecursively(@Nullable Path root)
По функциям аналогичен этому методу, но этот метод может вызывать исключения ввода-вывода.
copyRecursively
void copyRecursively(File src, File dest)
Рекурсивно скопируйте файл src в dest (целевой путь будет создан автоматически, если он не существует):
File src = new File("a");
File dest = new File("aa");
FileSystemUtils.copyRecursively(src, dest);
перегруженный методvoid copyRecursively(Path src, Path dest)
.
StreamUtils
Служебные методы, содержащие некоторые файловые потоки, имеют размер буфера по умолчанию 4096 байт.
Уведомление: Все методы этого класса инструментов не закроют поток!