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;
}
}
}
- 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());
}
}
}
}
- BeanPostProcessor–Bean后置处理器 – bean 实例级别
InstantiationAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
DestructionAwareBeanPostProcessor
SmartInstantiationAwareBeanPostProcessor
一、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),否则抛出异常,不予放行
void notNull(Object object, String message)
// 要求参数必须空(Null),否则抛出异常,不予『放行』。
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)
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)
static boolean isUrl(String resourceLocation)
static URL getURL(String resourceLocation)
// 获取文件(在 JAR 包内无法正常使用,需要是一个独立的文件)
static File getFile(String resourceLocation)
// URL 资源,如 file://... http://...
Method findMethod(Class<?> clazz, String name)
Method findMethod(Class clazz, String name, Class... paramTypes)
Method[] getAllDeclaredMethods(Class<?> leafClass)
Constructor accessibleConstructor(Class clazz, Class<?>... parameterTypes)
boolean isEqualsMethod(Method method)
boolean isHashCodeMethod(Method method)
boolean isToStringMethod(Method method)
boolean isObjectMethod(Method method)
boolean declaresException(Method method, Class<?> exceptionType)
Object invokeMethod(Method method, Object target)
Object invokeMethod(Method method, Object target, Object... args)
void makeAccessible(Method method)
void makeAccessible(Constructor<?> ctor)
Field findField(Class<?> clazz, String name)
Field findField(Class clazz, String name, Class type)
// 是否为一个 "public static final" 属性
boolean isPublicStaticFinal(Field 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)
void doWithFields(Class<?> clazz, ReflectionUtils.FieldCallback fc)
void doWithFields(Class<?> clazz, ReflectionUtils.FieldCallback fc,
ReflectionUtils.FieldFilter ff)
void doWithLocalFields(Class<?> clazz, ReflectionUtils.FieldCallback fc)
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)
getAnnotation: 从某个类获取某个annotation
findAnnotation: 从类或方法中查找某个annotation。
isAnnotationDeclaredLocally: 验证annotation是否直接注释在类上而不是集成来的。
isAnnotationInherited: 验证annotation是否继承于另一个class。
getAnnotationAttributes: 获取annotation的所有属性。
getDefaultValue: 获取指定annotation或annotation 属性的默认值
该工具类方法主要分为两类,一类是以get开头,一类是以find开头
get开头的:搜索直接声明的注解以及标有@Inherited父类注解
find开头的:会在父类和继承的接口上搜索注解,这些注解不需要标有元注解@Inherited。
getMergedAnnotationAttributes(),getMergedAnnotation(),getAllMergedAnnotations(),getMergedRepeatableAnnotations(),findMergedAnnotationAttributes(),findMergedAnnotation(),findAllMergedAnnotations()和findMergedRepeatableAnnotations()的所有变体都支持组合注解中带有属性覆盖的元注解的方法
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,
String convertResourcePathToClassName(String resourcePath)