All Downloads are FREE. Search and download functionalities are using the official Maven repository.

top.osjf.sdk.spring.beans.BeanPropertyUtils Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
/*
 * Copyright 2024-? the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package top.osjf.sdk.spring.beans;

import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.Description;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Role;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.MergedAnnotation;
import org.springframework.core.type.AnnotationMetadata;
import top.osjf.sdk.core.util.ArrayUtils;
import top.osjf.sdk.core.util.MapUtils;
import top.osjf.sdk.core.util.StringUtils;

import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Map;

/**
 * The relevant general method tool class for {@link BeanProperty}.
 *
 * @author zhangpengfei
 * @since 1.0.0
 */
public abstract class BeanPropertyUtils {

    /**
     * @see BeanProperty#autowire()
     */
    private static final String AUTOWIRE = "autowire";

    /**
     * @see BeanProperty#autowireCandidate()
     */
    private static final String AUTOWIRE_CANDIDATE = "autowireCandidate";

    /**
     * @see BeanProperty#scope()
     */
    private static final String SCOPE = "scope";

    /**
     * @see BeanProperty#role()
     */
    private static final String ROLE = "role";

    /**
     * @see BeanProperty#lazyInit()
     */
    private static final String LAZY = "lazyInit";

    /**
     * @see BeanProperty#description()
     */
    private static final String DESCRIPTION = "description";

    /**
     * Following the processing specification of {@link org.springframework.context.annotation.Bean},
     * the first name should be the main name of the bean.
     *
     * @param names Define a collection of names.
     * @return The primary name of the bean.
     */
    public static String getBeanName(String[] names) {
        if (ArrayUtils.isNotEmpty(names)) {
            return names[0];
        }
        return null;
    }

    /**
     * According to the definition specification of {@link org.springframework.context.annotation.Bean},
     * the non empty element array after removing the first element is
     * called an alias element array.
     *
     * @param names Define a collection of names.
     * @return alias name array.
     */
    public static String[] getAlisaNames(String[] names) {
        if (ArrayUtils.isNotEmpty(names)) {
            if (names.length == 1) {
                return null;
            }
            return new LinkedHashSet<>(Arrays.asList(
                    ArrayUtils.remove(names, 0))).toArray(new String[]{});
        }
        return null;
    }

    /**
     * The scope name setting of the bean supports annotations
     * {@link Scope} corresponding to attributes other than
     * {@link BeanProperty#scope()}}, and annotations are
     * used first.
     * 

Of course, when there is no direct existence of {@link Scope}, * search for the derived annotations of {@link Scope}. * If multiple derived annotations appear, the topmost one * will be selected as the scope definition option for this time. * * @param annotationMetadata Annotate metadata information. * @param defaultValue The default value when no annotations are provided. * @return Final logical value. */ public static String getMaybeAnnotationScope(AnnotationMetadata annotationMetadata, String defaultValue) { if (annotationMetadata.hasAnnotation(Scope.class.getCanonicalName())) { return getMaybeAnnotationValue(annotationMetadata, Scope.class, String.class, defaultValue); } MergedAnnotation mergedAnnotation = annotationMetadata.getAnnotations() .stream() .filter(m -> m.getType().isAnnotationPresent(Scope.class)) .min((o1, o2) -> { int o1_index = o1.getAggregateIndex(); int o2_index = o2.getAggregateIndex(); if (o1_index == o2_index) return 0; return o1_index > o2_index ? 1 : -1; }) .orElse(null); return mergedAnnotation != null ? mergedAnnotation.getType().getAnnotation(Scope.class).value() : defaultValue; } /** * The role setting of the bean supports annotations * {@link Role} corresponding to attributes other than * {@link BeanProperty#role()}}, and annotations are * used first. * * @param annotationMetadata Annotate metadata information. * @param defaultValue The default value when no annotations are provided. * @return Final logical value. */ public static int getMaybeAnnotationRole(AnnotationMetadata annotationMetadata, int defaultValue) { return getMaybeAnnotationValue(annotationMetadata, Role.class, int.class, defaultValue); } /** * The lazy load setting of the bean supports annotations * {@link Lazy} corresponding to attributes other than * {@link BeanProperty#lazyInit()}}, and annotations are * used first. * * @param annotationMetadata Annotate metadata information. * @param defaultValue The default value when no annotations are provided. * @return Final logical value. */ public static boolean getMaybeAnnotationLazy(AnnotationMetadata annotationMetadata, boolean defaultValue) { return getMaybeAnnotationValue(annotationMetadata, Lazy.class, boolean.class, defaultValue); } /** * The description information setting of the bean supports annotations * {@link Description} corresponding to attributes other than * {@link BeanProperty#description()}, and annotations are used first. * * @param annotationMetadata Annotate metadata information. * @param defaultValue The default value when no annotations are provided. * @return Final logical value. */ public static String getMaybeAnnotationDescription(AnnotationMetadata annotationMetadata, String defaultValue) { return getMaybeAnnotationValue(annotationMetadata, Description.class, String.class, defaultValue); } /** * Add support for special annotations that support certain defined * properties of annotation {@link BeanProperty}, with priority greater * than the value definition in this annotation. If present, return the * defined {@code value}. * * @param annotationMetadata Annotate metadata information. * @param annotationType Possible priority annotation types. * @param valueType The type of the final parsed value. * @param defaultValue The default value when no annotations are provided. * @param Possible priority annotation types. * @param The type of the final parsed value. * @return Final logical value. */ @SuppressWarnings("unchecked") private static T getMaybeAnnotationValue(AnnotationMetadata annotationMetadata, Class annotationType, Class valueType, T defaultValue) { String canonicalName = annotationType.getCanonicalName(); if (!annotationMetadata.hasAnnotation(canonicalName)) { return defaultValue; } Map annotationAttributes = annotationMetadata.getAnnotationAttributes(canonicalName); if (MapUtils.isEmpty(annotationAttributes)) { return defaultValue; } Object value = annotationAttributes.get("value"); if (valueType.isAssignableFrom(value.getClass())) { return (T) value; } throw new ClassCastException("Required type " + valueType.getName() + ", actual type " + value.getClass().getName() + "."); } /** * Fill {@link BeanProperty} with the relevant properties of {@link BeanDefinition} and * call the relevant methods for building the class. * * @param builder The construction class of {@link BeanDefinition}. * @param annotationMetadata Annotate metadata information. * @param beanPropertyAttributes Encapsulation of {@link BeanProperty}'s properties. * @return A BeanDefinition describes a bean instance after full use {@link BeanProperty}. */ public static BeanDefinition fullBeanDefinition(BeanDefinitionBuilder builder, AnnotationMetadata annotationMetadata, AnnotationAttributes beanPropertyAttributes) { Autowire autowire = beanPropertyAttributes.getEnum(AUTOWIRE); boolean autowireCandidate = beanPropertyAttributes.getBoolean(AUTOWIRE_CANDIDATE); String scope = getMaybeAnnotationScope(annotationMetadata, beanPropertyAttributes.getString(SCOPE)); int role = getMaybeAnnotationRole(annotationMetadata, beanPropertyAttributes.getNumber(ROLE)); boolean lazyInit = getMaybeAnnotationLazy(annotationMetadata, beanPropertyAttributes.getBoolean(LAZY)); String description = getMaybeAnnotationDescription(annotationMetadata, beanPropertyAttributes.getString(DESCRIPTION)); //—————————————————————————— General attributes —————————————————————————— builder.setScope(scope); builder.setAutowireMode(autowire.value()); builder.setRole(role); builder.setLazyInit(lazyInit); //—————————————————————————— Pre inspection —————————————————————————— BeanDefinition beanDefinition = builder.getBeanDefinition(); //—————————————————————————— BeanDefinition attributes —————————————————————————— beanDefinition.setAutowireCandidate(autowireCandidate); if (StringUtils.isNotBlank(description)) beanDefinition.setDescription(description); return beanDefinition; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy