0
点赞
收藏
分享

微信扫一扫

java 小工具 (Spring 工具类) (一)


文章目录

  • ​​1.BeanDefinitionReaderUtils​​
  • ​​1.1 createBeanDefinition​​
  • ​​1.2 generateBeanName​​
  • ​​1.3 registerBeanDefinition​​
  • ​​1.4 registerWithGeneratedName​​
  • ​​2.ConfigurationClassUtils​​
  • ​​2.1 ConfigurationClassUtils类属性源码解析​​
  • ​​2.2 checkConfigurationClassCandidate​​
  • ​​2.3 isConfigurationCandidate​​
  • ​​2.4 getOrder​​

1.BeanDefinitionReaderUtils

Bean注册器

java 小工具 (Spring 工具类) (一)_java

1.1 createBeanDefinition

创建BeanDefinition

public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {

GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}

通过封装BeanDefinition, 返回封装后的BeanDefinition

1.2 generateBeanName

生成BeanName

public static String generateBeanName(
BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
throws BeanDefinitionStoreException {

String generatedBeanName = definition.getBeanClassName();
if (generatedBeanName == null) {
if (definition.getParentName() != null) {
generatedBeanName = definition.getParentName() + "$child";
}
else if (definition.getFactoryBeanName() != null) {
generatedBeanName = definition.getFactoryBeanName() + "$created";
}
}
if (!StringUtils.hasText(generatedBeanName)) {
throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
}

if (isInnerBean) {
// Inner bean: generate identity hashcode suffix.
return generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
}

// Top-level bean: use plain class name with unique suffix if necessary.
return uniqueBeanName(generatedBeanName, registry);
}

1.3 registerBeanDefinition

注册Bean定义,它这里需要Bean定义和注册器

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {

// Register bean definition under primary name.
// 获取Bean名称
String beanName = definitionHolder.getBeanName();
// 注册Bean定义
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// Register aliases for bean name, if any.
// 注册别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String aliase : aliases) {
registry.registerAlias(beanName, aliase);
}
}

1.4 registerWithGeneratedName

通过生成的名称来注册Bean

/**
* Register the given bean definition with a generated name,
* unique within the given bean factory.
*
* 用自动生成的Bean名称来注册Bean
*
* @param definition the bean definition to generate a bean name for
* @param registry the bean factory to register with
* @return the generated bean name
* @throws BeanDefinitionStoreException if no unique name can be generated
* for the given bean definition or the definition cannot be registered
*/
public static String registerWithGeneratedName(AbstractBeanDefinition definition, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {

// 获取生成的Bean名称
String generatedName = generateBeanName(definition, registry, false);
registry.registerBeanDefinition(generatedName, definition);
return generatedName;
}

2.ConfigurationClassUtils

ConfigurationClass配置类的实用程序.

如果bean定义是一个被@Configuration标注的JavaConfig配置类, 则bean定义属性设置为full标记;

如果bean定义被@Component、@ComponentScan、@Import、@ImportResource注解标注或者方法被@Bean标注,则bean定义属性设置为lite。

如果bean定义被设置了full或者lite属性,则如果存在设置bean定义的order属性

java 小工具 (Spring 工具类) (一)_edn_02

2.1 ConfigurationClassUtils类属性源码解析

//configuration class如果是@Configuration注解标注的类属性标注为full
public static final String CONFIGURATION_CLASS_FULL = "full";
//非@Configuration注解标注的类(@Component、@Import等注解标注)属性标注为lite
public static final String CONFIGURATION_CLASS_LITE = "lite";
//即值:org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass作为属性配置类型标记属性的key
public static final String CONFIGURATION_CLASS_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
//即值:org.springframework.context.annotation.ConfigurationClassPostProcessor.order配置属性配置类排序的属性key
private static final String ORDER_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "order");


private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
//字典,存储标注配置类的注解
private static final Set<String> candidateIndicators = new HashSet<>(8);

static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}

2.2 checkConfigurationClassCandidate

检查给定的bean定义是否是配置类(或在configuration/component类中声明的嵌套组件类,也要自动注册)的候选项,并相应地标记它。

public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
//获取bean定义的class类名
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}

AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// 检查已经加载的类,如果存在的话
// 因为我们甚至可能无法加载这个类的类文件
//获取bean定义的class实例对象,如果class实例是下面四种类或接口的相同、子类、父接口等任何一种情况,直接返回
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
//使用反射为给定类创建新的AnnotationMetadata实例
metadata = AnnotationMetadata.introspect(beanClass);
}
else {
try {
//获取className的MetadataReader实例
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
//读取底层类的完整注释元数据,包括带注释方法的元数据
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
}
//获取bean定义的元数据被@Configuration注解标注的属性字典值
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
//如果bean被@Configuration注解标注,且属性proxyBeanMethods为false(使用代理模式)
//则将bean定义标记为full
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
//如果bean被@Configuration注解标注,且被注解@Component、@ComponentScan、@Import、@ImportResource
//或@Bean标记的方法,则将bean定义标记为lite
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}

// bean定义是一个标记为full或lite的候选项,如果设置order则设置order属性值
Integer order = getOrder(metadata);
if (order != null) {
//设置bean定义的order值
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}

return true;
}

2.3 isConfigurationCandidate

检查给定的元数据,以查找给定的候选配置类是否被指定的注解标注

public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
//不考虑接口或注解
if (metadata.isInterface()) {
return false;
}

// 检查是否被注解@Component、@ComponentScan、@Import、@ImportResource标注
for (String indicator : candidateIndicators) {
if (metadata.isAnnotated(indicator)) {
return true;
}
}

// 最后检查是否有@Bean标注的方法
try {
return metadata.hasAnnotatedMethods(Bean.class.getName());
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
}
return false;
}
}

2.4 getOrder

获取被@Order标注的排序值

@Nullable
public static Integer getOrder(AnnotationMetadata metadata) {
Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);
}


举报

相关推荐

0 条评论