spring的常用知识点汇总

151 阅读14分钟

1、spring各种PostProcessor

1)BeanDefinitionRegistryPostProcessor– BeanDefinitionRegistry后置处理器 – 容器级别(继承BeanFactoryPostProcessor)

执行时机 : 在BeanDefinitionRegistry的标准初始化之后所有其他一般的BeanFactoryPostProcessor执行之前执行,此时所有的bean定义已经加载但是还没有bean实例被创建。

示例:

package org.mybatis.spring.mapper;

 

import java.lang.annotation.Annotation;

import java.util.Iterator;

import java.util.Map;

import java.util.Objects;

import java.util.Optional;

import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.SqlSessionTemplate;

import org.springframework.beans.PropertyValue;

import org.springframework.beans.PropertyValues;

import org.springframework.beans.factory.BeanNameAware;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import org.springframework.beans.factory.config.PropertyResourceConfigurer;

import org.springframework.beans.factory.config.TypedStringValue;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

import org.springframework.beans.factory.support.BeanNameGenerator;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.core.env.Environment;

import org.springframework.util.Assert;

import org.springframework.util.StringUtils;

 

public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {

    private String basePackage;

    private boolean addToConfig = true;

    private String lazyInitialization;

    private SqlSessionFactory sqlSessionFactory;

    private SqlSessionTemplate sqlSessionTemplate;

    private String sqlSessionFactoryBeanName;

    private String sqlSessionTemplateBeanName;

    private Class<? extends Annotation> annotationClass;

    private Class<?> markerInterface;

    private Class<? extends MapperFactoryBean> mapperFactoryBeanClass;

    private ApplicationContext applicationContext;

    private String beanName;

    private boolean processPropertyPlaceHolders;

    private BeanNameGenerator nameGenerator;

 

    public MapperScannerConfigurer() {

    }

 

    public void setBasePackage(String basePackage) {

        this.basePackage = basePackage;

    }

 

    public void setAddToConfig(boolean addToConfig) {

        this.addToConfig = addToConfig;

    }

 

    public void setLazyInitialization(String lazyInitialization) {

        this.lazyInitialization = lazyInitialization;

    }

 

    public void setAnnotationClass(Class<? extends Annotation> annotationClass) {

        this.annotationClass = annotationClass;

    }

 

    public void setMarkerInterface(Class<?> superClass) {

        this.markerInterface = superClass;

    }

 

    /** @deprecated */

    @Deprecated

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {

        this.sqlSessionTemplate = sqlSessionTemplate;

    }

 

    public void setSqlSessionTemplateBeanName(String sqlSessionTemplateName) {

        this.sqlSessionTemplateBeanName = sqlSessionTemplateName;

    }

 

    /** @deprecated */

    @Deprecated

    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {

        this.sqlSessionFactory = sqlSessionFactory;

    }

 

    public void setSqlSessionFactoryBeanName(String sqlSessionFactoryName) {

        this.sqlSessionFactoryBeanName = sqlSessionFactoryName;

    }

 

    public void setProcessPropertyPlaceHolders(boolean processPropertyPlaceHolders) {

        this.processPropertyPlaceHolders = processPropertyPlaceHolders;

    }

 

    public void setMapperFactoryBeanClass(Class<? extends MapperFactoryBean> mapperFactoryBeanClass) {

        this.mapperFactoryBeanClass = mapperFactoryBeanClass;

    }

 

    public void setApplicationContext(ApplicationContext applicationContext) {

        this.applicationContext = applicationContext;

    }

 

    public void setBeanName(String name) {

        this.beanName = name;

    }

 

    public BeanNameGenerator getNameGenerator() {

        return this.nameGenerator;

    }

 

    public void setNameGenerator(BeanNameGenerator nameGenerator) {

        this.nameGenerator = nameGenerator;

    }

 

    public void afterPropertiesSet() throws Exception {

        Assert.notNull(this.basePackage, "Property 'basePackage' is required");

    }

 

    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    }

 

    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {

        if (this.processPropertyPlaceHolders) {

            this.processPropertyPlaceHolders();

        }

 

        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

        scanner.setAddToConfig(this.addToConfig);

        scanner.setAnnotationClass(this.annotationClass);

        scanner.setMarkerInterface(this.markerInterface);

        scanner.setSqlSessionFactory(this.sqlSessionFactory);

        scanner.setSqlSessionTemplate(this.sqlSessionTemplate);

        scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);

        scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);

        scanner.setResourceLoader(this.applicationContext);

        scanner.setBeanNameGenerator(this.nameGenerator);

        scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);

        if (StringUtils.hasText(this.lazyInitialization)) {

            scanner.setLazyInitialization(Boolean.valueOf(this.lazyInitialization));

        }

 

        scanner.registerFilters();

        scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ",; \t\n"));

    }

 

    private void processPropertyPlaceHolders() {

        Map<String, PropertyResourceConfigurer> prcs = this.applicationContext.getBeansOfType(PropertyResourceConfigurer.class);

        if (!prcs.isEmpty() && this.applicationContext instanceof ConfigurableApplicationContext) {

            BeanDefinition mapperScannerBean = ((ConfigurableApplicationContext)this.applicationContext).getBeanFactory().getBeanDefinition(this.beanName);

            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

            factory.registerBeanDefinition(this.beanName, mapperScannerBean);

            Iterator var4 = prcs.values().iterator();

 

            while(var4.hasNext()) {

                PropertyResourceConfigurer prc = (PropertyResourceConfigurer)var4.next();

                prc.postProcessBeanFactory(factory);

            }

 

            PropertyValues values = mapperScannerBean.getPropertyValues();

            this.basePackage = this.updatePropertyValue("basePackage", values);

            this.sqlSessionFactoryBeanName = this.updatePropertyValue("sqlSessionFactoryBeanName", values);

            this.sqlSessionTemplateBeanName = this.updatePropertyValue("sqlSessionTemplateBeanName", values);

            this.lazyInitialization = this.updatePropertyValue("lazyInitialization", values);

        }

 

        Optional var10001 = Optional.ofNullable(this.basePackage);

        Environment var10002 = this.getEnvironment();

        Objects.requireNonNull(var10002);

        this.basePackage = (String)var10001.map(var10002::resolvePlaceholders).orElse((Object)null);

        var10001 = Optional.ofNullable(this.sqlSessionFactoryBeanName);

        var10002 = this.getEnvironment();

        Objects.requireNonNull(var10002);

        this.sqlSessionFactoryBeanName = (String)var10001.map(var10002::resolvePlaceholders).orElse((Object)null);

        var10001 = Optional.ofNullable(this.sqlSessionTemplateBeanName);

        var10002 = this.getEnvironment();

        Objects.requireNonNull(var10002);

        this.sqlSessionTemplateBeanName = (String)var10001.map(var10002::resolvePlaceholders).orElse((Object)null);

        var10001 = Optional.ofNullable(this.lazyInitialization);

        var10002 = this.getEnvironment();

        Objects.requireNonNull(var10002);

        this.lazyInitialization = (String)var10001.map(var10002::resolvePlaceholders).orElse((Object)null);

    }

 

    private Environment getEnvironment() {

        return this.applicationContext.getEnvironment();

    }

 

    private String updatePropertyValue(String propertyName, PropertyValues values) {

        PropertyValue property = values.getPropertyValue(propertyName);

        if (property == null) {

            return null;

        } else {

            Object value = property.getValue();

            if (value == null) {

                return null;

            } else if (value instanceof String) {

                return value.toString();

            } else {

                return value instanceof TypedStringValue ? ((TypedStringValue)value).getValue() : null;

            }

        }

    }

}

//

// Source code recreated from a .class file by IntelliJ IDEA

// (powered by Fernflower decompiler)

//

 

package org.mybatis.spring.mapper;

 

import java.lang.annotation.Annotation;

import java.util.Arrays;

import java.util.Iterator;

import java.util.Set;

import org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.logging.Logger;

import org.mybatis.logging.LoggerFactory;

import org.mybatis.spring.SqlSessionTemplate;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;

import org.springframework.beans.factory.config.BeanDefinition;

import org.springframework.beans.factory.config.BeanDefinitionHolder;

import org.springframework.beans.factory.config.RuntimeBeanReference;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;

import org.springframework.beans.factory.support.GenericBeanDefinition;

import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

import org.springframework.core.type.filter.AnnotationTypeFilter;

import org.springframework.core.type.filter.AssignableTypeFilter;

import org.springframework.util.StringUtils;

 

public class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {

    private static final Logger LOGGER = LoggerFactory.getLogger(ClassPathMapperScanner.class);

    private boolean addToConfig = true;

    private boolean lazyInitialization;

    private SqlSessionFactory sqlSessionFactory;

    private SqlSessionTemplate sqlSessionTemplate;

    private String sqlSessionTemplateBeanName;

    private String sqlSessionFactoryBeanName;

    private Class<? extends Annotation> annotationClass;

    private Class<?> markerInterface;

    private Class<? extends MapperFactoryBean> mapperFactoryBeanClass = MapperFactoryBean.class;

 

    public ClassPathMapperScanner(BeanDefinitionRegistry registry) {

        super(registry, false);

    }

 

    public void setAddToConfig(boolean addToConfig) {

        this.addToConfig = addToConfig;

    }

 

    public void setAnnotationClass(Class<? extends Annotation> annotationClass) {

        this.annotationClass = annotationClass;

    }

 

    public void setLazyInitialization(boolean lazyInitialization) {

        this.lazyInitialization = lazyInitialization;

    }

 

    public void setMarkerInterface(Class<?> markerInterface) {

        this.markerInterface = markerInterface;

    }

 

    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {

        this.sqlSessionFactory = sqlSessionFactory;

    }

 

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {

        this.sqlSessionTemplate = sqlSessionTemplate;

    }

 

    public void setSqlSessionTemplateBeanName(String sqlSessionTemplateBeanName) {

        this.sqlSessionTemplateBeanName = sqlSessionTemplateBeanName;

    }

 

    public void setSqlSessionFactoryBeanName(String sqlSessionFactoryBeanName) {

        this.sqlSessionFactoryBeanName = sqlSessionFactoryBeanName;

    }

 

    /** @deprecated */

    @Deprecated

    public void setMapperFactoryBean(MapperFactoryBean<?> mapperFactoryBean) {

        this.mapperFactoryBeanClass = mapperFactoryBean == null ? MapperFactoryBean.class : mapperFactoryBean.getClass();

    }

 

    public void setMapperFactoryBeanClass(Class<? extends MapperFactoryBean> mapperFactoryBeanClass) {

        this.mapperFactoryBeanClass = mapperFactoryBeanClass == null ? MapperFactoryBean.class : mapperFactoryBeanClass;

    }

 

    public void registerFilters() {

        boolean acceptAllInterfaces = true;

        if (this.annotationClass != null) {

            this.addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));

            acceptAllInterfaces = false;

        }

 

        if (this.markerInterface != null) {

            this.addIncludeFilter(new AssignableTypeFilter(this.markerInterface) {

                protected boolean matchClassName(String className) {

                    return false;

                }

            });

            acceptAllInterfaces = false;

        }

 

        if (acceptAllInterfaces) {

            this.addIncludeFilter((metadataReader, metadataReaderFactory) -> {

                return true;

            });

        }

 

        this.addExcludeFilter((metadataReader, metadataReaderFactory) -> {

            String className = metadataReader.getClassMetadata().getClassName();

            return className.endsWith("package-info");

        });

    }

 

    public Set<BeanDefinitionHolder> doScan(String... basePackages) {

        Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);

        if (beanDefinitions.isEmpty()) {

            LOGGER.warn(() -> {

                return "No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.";

            });

        } else {

            this.processBeanDefinitions(beanDefinitions);

        }

 

        return beanDefinitions;

    }

 

    private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {

        GenericBeanDefinition definition;

        for(Iterator var3 = beanDefinitions.iterator(); var3.hasNext(); definition.setLazyInit(this.lazyInitialization)) {

            BeanDefinitionHolder holder = (BeanDefinitionHolder)var3.next();

            definition = (GenericBeanDefinition)holder.getBeanDefinition();

            String beanClassName = definition.getBeanClassName();

            LOGGER.debug(() -> {

                return "Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + beanClassName + "' mapperInterface";

            });

            definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);

            definition.setBeanClass(this.mapperFactoryBeanClass);

            definition.getPropertyValues().add("addToConfig", this.addToConfig);

            boolean explicitFactoryUsed = false;

            if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {

                definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));

                explicitFactoryUsed = true;

            } else if (this.sqlSessionFactory != null) {

                definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);

                explicitFactoryUsed = true;

            }

 

            if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {

                if (explicitFactoryUsed) {

                    LOGGER.warn(() -> {

                        return "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.";

                    });

                }

 

                definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));

                explicitFactoryUsed = true;

            } else if (this.sqlSessionTemplate != null) {

                if (explicitFactoryUsed) {

                    LOGGER.warn(() -> {

                        return "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.";

                    });

                }

 

                definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);

                explicitFactoryUsed = true;

            }

 

            if (!explicitFactoryUsed) {

                LOGGER.debug(() -> {

                    return "Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.";

                });

                definition.setAutowireMode(2);

            }

        }

 

    }

 

    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {

        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();

    }

 

    protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) {

        if (super.checkCandidate(beanName, beanDefinition)) {

            return true;

        } else {

            LOGGER.warn(() -> {

                return "Skipping MapperFactoryBean with name '" + beanName + "' and '" + beanDefinition.getBeanClassName() + "' mapperInterface. Bean already defined with the same name!";

            });

            return false;

        }

    }

}
  1. BeanFactoryPostProcessor–BeanFactory后置处理器 – 容器级别

执行时机 : 在BeanFactory的标准初始化之后并且所有的BeanDefinitionRegistryPostProcessor执行之后,此时所有的bean定义已经加载但是bean实例尚未创建。

示例:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        System.out.println("[MyBeanFactoryPostProcessor]调用了postProcessBeanFactory");

        int count = beanFactory.getBeanDefinitionCount();

        System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory共有" + count + "个bean");

        String[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();

        System.out.println("[MyBeanFactoryPostProcessor]当前beanFactory有下面组件" + Arrays.asList(beanDefinitionNames));

        //获取容器中所有的beanDefinition

        for (String beanName : beanDefinitionNames) {

            if ("person".equals(beanName)) {

                //获取PersonDefinition对象

                BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);

                MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();

                System.out.println(propertyValues.toString());

                //修改定义中的name属性值

                propertyValues.addPropertyValue("name", "赵四");

                System.out.println("[MyBeanFactoryPostProcessor]postProcessBeanFactory方法中修改了name属性初始值了");

                System.out.println(propertyValues.toString());

            }

        }

    }

}
  1. BeanPostProcessor–Bean后置处理器 – bean 实例级别

实际应用中又可细分为如下几类 :

InstantiationAwareBeanPostProcessor

MergedBeanDefinitionPostProcessor

DestructionAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor

一般BeanPostProcessor

流程时序:

image.png

一、SmartInstantiationAwareBeanPostProcessor

predictBeanType方法用于预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null。主要在于BeanDefinition无法确定Bean类型的时候调用该方法来确定类型

determineCandidateConstructors方法用于选择合适的构造器,比如类有多个构造器,可以实现这个方法选择合适的构造器并用于实例化对象。该方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用,如果postProcessBeforeInstantiation方法返回了一个新的实例代替了原本该生成的实例,那么该方法会被忽略

getEarlyBeanReference主要用于解决循环引用问题。比如ReferenceA实例内部有ReferenceB的引用,ReferenceB实例内部有ReferenceA的引用。首先先实例化ReferenceA,实例化完成之后提前把这个bean暴露在ObjectFactory中,然后populate属性,这个时候发现需要ReferenceB。然后去实例化ReferenceB,在实例化ReferenceB的时候它需要ReferenceA的实例才能继续,这个时候就会去ObjectFactory中找出了ReferenceA实例,ReferenceB顺利实例化。ReferenceB实例化之后,ReferenceA的populate属性过程也成功完成,注入了ReferenceB实例。提前把这个bean暴露在ObjectFactory中,这个ObjectFactory获取的实例就是通过getEarlyBeanReference方法得到的

二、BeanPostProcessor

postProcessBeforeInitialization是指bean在初始化之前需要调用的方法

postProcessAfterInitialization是指bean在初始化之后需要调用的方法

postProcessBeforeInitialization和postProcessAfterInitialization方法被调用的时候。这个时候bean已经被实例化,并且所有该注入的属性都已经被注入,是一个完整的bean

这2个方法的返回值可以是原先生成的实例bean,或者使用wrapper包装这个实例

三、DestructionAwareBeanPostProcessor

postProcessBeforeDestruction该方法是bean在Spring在容器中被销毁之前调用

四、MergedBeanDefinitionPostProcessor

postProcessMergedBeanDefinition该方法是bean在合并Bean定义之后调用

五.InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走

postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。如果该方法返回false,会忽略属性值的设置;如果返回true,会按照正常流程设置属性值

postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法不会被调用。可以在该方法内对属性值进行修改

父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的

Instantiation表示实例化,Initialization表示初始化。实例化的意思在对象还未生成,初始化的意思在对象已经生成

2、spring的各种aware接口

aware接口:是一个接口,里面空白一片,没有任何方法,它是一个空荡荡的定义,一种标记。

aware接口作用:可以让调用者获取到某些信息,例如:加载当前Bean的容器名,当前Bean在容器中的BeanName,获取一些文本信息和资源文件等等,去获取加载当前Bean的加载器信息,等等等等。

aware使用示例:

@Service

public class DemoService implements BeanNameAware, BeanClassLoaderAware {

 

    private String beanName;

    private String classLoader;

 

    @Override

    public void setBeanName(String name) {

        beanName = name;

    }

 

    public String getBeanName() {

        return beanName;

    }

 

    @Override

    public void setBeanClassLoader(ClassLoader classLoader) {

        this.classLoader = classLoader.toString();

    }

 

    public String getClassLoader() {

        return classLoader;

    }

}

SpringBoot提供了大致一下的一些Aware接口的实现接口:

ApplicationContextAware,ApplicationEventPublisherAware, BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, EmbeddedValueResolverAware, EnvironmentAware, ImportAware, LoadTimeWeaverAware, MessageSourceAware, NotificationPublisherAware, ResourceLoaderAware

3、spring常用工具类

1、 Assert 断言工具类

// 要求参数 object 必须为非空(Not Null),否则抛出异常,不予放行

// 参数 message 参数用于定制异常信息。

void notNull(Object object, String message)

// 要求参数必须空(Null),否则抛出异常,不予『放行』。

// 和 notNull() 方法断言规则相反

void isNull(Object object, String message)

// 要求参数必须为真(True),否则抛出异常,不予『放行』。

void isTrue(boolean expression, String message)

// 要求参数(List/Set)必须非空(Not Empty),否则抛出异常,不予放行

void notEmpty(Collection collection, String message)

// 要求参数(String)必须有长度(即,Not Empty),否则抛出异常,不予放行

void hasLength(String text, String message)

// 要求参数(String)必须有内容(即,Not Blank),否则抛出异常,不予放行

void hasText(String text, String message)

// 要求参数是指定类型的实例,否则抛出异常,不予放行

void isInstanceOf(Class type, Object obj, String message)

// 要求参数 subType 必须是参数 superType 的子类或实现类,否则抛出异常,不予放行

void isAssignable(Class superType, Class subType, String message)

2、 StringUtils

// 解析路径字符串,优化其中的 “..”

String cleanPath(String path)

// 解析路径字符串,解析出文件名部分

String getFilename(String path)

// 解析路径字符串,解析出文件后缀名

String getFilenameExtension(String path)

// 比较两个两个字符串,判断是否是同一个路径。会自动处理路径中的 “..”

boolean pathEquals(String path1, String path2)

// 删除文件路径名中的后缀部分

String stripFilenameExtension(String path)

// 以 “. 作为分隔符,获取其最后一部分

String unqualify(String qualifiedName)

// 以指定字符作为分隔符,获取其最后一部分

String unqualify(String qualifiedName, char separator)

3、 ResourceUtils

// 判断字符串是否是一个合法的 URL 字符串。

static boolean isUrl(String resourceLocation)

// 获取 URL

static URL getURL(String resourceLocation)

// 获取文件(在 JAR 包内无法正常使用,需要是一个独立的文件)

static File getFile(String resourceLocation)

// 文件系统资源 D:...

FileSystemResource

// URL 资源,如 file://... http://...

UrlResource

// 类路径下的资源,classpth:...

ClassPathResource

// Web 容器上下文中的资源(jar 包、war 包)

ServletContextResource

// 判断资源是否存在

boolean exists()

// 从资源中获得 File 对象

File getFile()

// 从资源中获得 URI 对象

URI getURI()

// 从资源中获得 URI 对象

URL getURL()

// 获得资源的 InputStream

InputStream getInputStream()

// 获得资源的描述信息

String getDescription()

4、 ReflectionUtils

 获取方法

// 在类中查找指定方法

Method findMethod(Class<?> clazz, String name)

// 同上,额外提供方法参数类型作查找条件

Method findMethod(Class clazz, String name, Class... paramTypes)

// 获得类中所有方法,包括继承而来的

Method[] getAllDeclaredMethods(Class<?> leafClass)

// 在类中查找指定构造方法

Constructor accessibleConstructor(Class clazz, Class<?>... parameterTypes)

// 是否是 equals() 方法

boolean isEqualsMethod(Method method)

// 是否是 hashCode() 方法

boolean isHashCodeMethod(Method method)

// 是否是 toString() 方法

boolean isToStringMethod(Method method)

// 是否是从 Object 类继承而来的方法

boolean isObjectMethod(Method method)

// 检查一个方法是否声明抛出指定异常

boolean declaresException(Method method, Class<?> exceptionType)

2、执行方法

// 执行方法

Object invokeMethod(Method method, Object target)

// 同上,提供方法参数

Object invokeMethod(Method method, Object target, Object... args)

// 取消 Java 权限检查。以便后续执行该私有方法

void makeAccessible(Method method)

// 取消 Java 权限检查。以便后续执行私有构造方法

void makeAccessible(Constructor<?> ctor)

3、获取字段

// 在类中查找指定属性

Field findField(Class<?> clazz, String name)

// 同上,多提供了属性的类型

Field findField(Class clazz, String name, Class type)

// 是否为一个 "public static final" 属性

boolean isPublicStaticFinal(Field field)

4、设置字段

// 获取 target 对象的 field 属性值

Object getField(Field field, Object target)

// 设置 target 对象的 field 属性值,值为 value

void setField(Field field, Object target, Object value)

// 同类对象属性对等赋值

void shallowCopyFieldState(Object src, Object dest)

// 取消 Java 的权限控制检查。以便后续读写该私有属性

void makeAccessible(Field field)

// 对类的每个属性执行 callback

void doWithFields(Class<?> clazz, ReflectionUtils.FieldCallback fc)

// 同上,多了个属性过滤功能。

void doWithFields(Class<?> clazz, ReflectionUtils.FieldCallback fc,

ReflectionUtils.FieldFilter ff)

// 同上,但不包括继承而来的属性

void doWithLocalFields(Class<?> clazz, ReflectionUtils.FieldCallback fc)

5、AopUtils

// 判断是不是 Spring 代理对象

boolean isAopProxy()

// 判断是不是 jdk 动态代理对象

isJdkDynamicProxy()

// 判断是不是 CGLIB 代理对象

boolean isCglibProxy()

// 获取被代理的目标 class

Class<?> getTargetClass()

6、 AopProxyUtils

//获取一个代理对象的最终对象类型

Class<?> ultimateTargetClass(Object candidate)

// 判断一个advised真正需要代理的目标接口列表。简单理解,比如在spring使用JDK proxy做代理的时候,这个方法返回的类型列表就是真正需要交给Proxy.newProxyInstance方法的接口列表

Class<?>[] completeProxiedInterfaces(AdvisedSupport advised)

// 获取一个代理对象中的用户定义的接口,即非(Advised接口体系)之外的其他接口

Class<?>[] proxiedUserInterfaces(Object proxy) 

// 判断两个(即将)代理出来的对象是否拥有相同接口;

boolean equalsProxiedInterfaces(AdvisedSupport a, AdvisedSupport b)

// 判断两个(即将)代理出来的对象是否拥有相同的建议者(Advisor);

boolean equalsAdvisors(AdvisedSupport a, AdvisedSupport b)

//  判断两个(即将)代理出来的对象是否相同;

boolean equalsInProxy(AdvisedSupport a, AdvisedSupport b)

7、 AnnotationUtils

 getAnnotation: 从某个类获取某个annotation

 findAnnotation: 从类或方法中查找某个annotation。

 isAnnotationDeclaredLocally: 验证annotation是否直接注释在类上而不是集成来的。

 isAnnotationInherited: 验证annotation是否继承于另一个class。

 getAnnotationAttributes: 获取annotation的所有属性。

 getValue: 获取指定annotation的值. 

 getDefaultValue: 获取指定annotation或annotation 属性的默认值

8、 AnnotatedElementUtils

该工具类方法主要分为两类,一类是以get开头,一类是以find开头

get开头的:搜索直接声明的注解以及标有@Inherited父类注解

find开头的:会在父类和继承的接口上搜索注解,这些注解不需要标有元注解@Inherited。

getMergedAnnotationAttributes(),getMergedAnnotation(),getAllMergedAnnotations(),getMergedRepeatableAnnotations(),findMergedAnnotationAttributes(),findMergedAnnotation(),findAllMergedAnnotations()和findMergedRepeatableAnnotations()的所有变体都支持组合注解中带有属性覆盖的元注解的方法

9、 ClassUtils

// 获取默认类加载器

ClassLoader getDefaultClassLoader()

//这个方法较为简单,使用传入的classloader替换线程的classloader;使用场景,比如一个线程的classloader和spring的classloader不一致的时候,就可以使用这个方法替换;

ClassLoader overrideThreadContextClassLoader(ClassLoader classLoaderToUse)

// 通过指定的classloader加载对应的类;除了能正常加载普通的类型,还能加载简单类型,数组,或者内部类

Class<?> forName(String name, ClassLoader classLoader) throws ClassNotFoundException, LinkageError

// 同上

Class<?> resolveClassName(String className, ClassLoader classLoader) throws IllegalArgumentException

// 获取简单类型的类

Class<?> resolvePrimitiveClassName(String name)

// 获取用户定义的本来的类型,大部分情况下就是类型本身,主要针对cglib做了额外的判断,获取cglib代理之后的父类

Class getUserClass(Class clazz)

// 得到类上指定的public方法;其实现也是一个标准的反射使用:

Method getMethod(Class clazz, String methodName, Class… paramTypes)

// 获取指定类中匹配该方法名称的方法个数,包括非public方法

int getMethodCountForName(Class<?> clazz, String methodName)

// 判定指定的类及其父类中是否包含指定方法名称的方法,包括非public方法

boolean hasAtLeastOneMethodWithName(Class<?> clazz, String methodName)

// 获得最匹配的一个可以执行的方法;比如传入IEmployeeService.someLogic方法,在EmployeeServiceImpl类上找到匹配的EmployeeServiceImpl.someLogic方法,这个方法是一个可以执行的方法

Method getMostSpecificMethod(Method method, Class<?> targetClass)

// 判定一个方法是否是用户可用的方法

boolean isUserLevelMethod(Method method)

// 判定一个类是否是简单类型的包装类;

boolean isPrimitiveWrapper(Class<?> clazz)

// 判定一个类是否是简单类型,或者是简单类型的包装类型;

boolean isPrimitiveOrWrapper(Class<?> clazz)

// 一个代理类型,并且该类型实现了指定的接口

Class<?> getProxyClass(ClassLoader loader,

Class<?>… interfaces)

//  把文件路径形式变成包路径形式

String convertResourcePathToClassName(String resourcePath)

// 把类路径形式变成文件路径形式

String convertClassNameToResourcePath(String className)

把类路径形式变成文件路径形式;