Spring中bean生命周期的PostProcessor的每个方法的作用

news2024/11/26 8:30:59

可结合这个博客看
https://blog.csdn.net/riemann_/article/details/118500805、https://cloud.tencent.com/developer/article/1409315、https://blog.csdn.net/qq_43631716/article/details/120239438
本篇内容借鉴于chatgtp,应该有错误,仅作方法应用的参考,如有错误,请指出

在这里插入图片描述

InstantiationAwareBeanPostProcessor类是什么作用?
该类继承于BeanPostProcessor,是 Spring Framework 中的一个接口,用于在 Spring 容器实例化 bean 实例过程中的各个阶段插入自定义的逻辑,提供了以下几个方法,可以让开发者在不同的 bean 实例化阶段进行干预:

  1. postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在实例化 bean 之前(doCreatebean()方法)被调用,允许你返回一个实例来替代默认的实例化过程。如果在这里返回非空实例,则 Spring将跳过默认的实例化步骤。
  2. .postProcessAfterInstantiation(Object bean, String beanName): 在实例化 bean 之后(doCreatebean()方法)被调用,允许你在实例化完成后进行一些自定义的操作。
  3. postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName): 在 bean 的属性注入之前(populateBean()方法)被调用,允许你对属性进行自定义操作。
  4. .postProcessBeforeInitialization(Object bean, String beanName): 在 bean 的初始化方法(比如 @PostConstruct 注解标记的方法)之前被调用,允许你在初始化之前进行一些操作。
  5. postProcessAfterInitialization(Object bean, String beanName): 在 bean 的初始化方法之后被调用,允许你在初始化之后进行一些操作。

applyBeanPostProcessorsBeforeInstantiation()方法的作用

  1. 获取所有已注册的 BeanPostProcessor 对象。
  2. 遍历这些 BeanPostProcessor,依次调用它们postProcessBeforeInstantiation 方法,传递要实例化的 bean 类型和 bean 的名称作为参数。
  3. 如果某个 BeanPostProcessor 返回非空实例(即返回了一个代替默认实例化过程的对象),则将使用该实例作为 bean实例,并终止默认的实例化过程;否则,继续默认的实例化过程。

这个方法的主要目的是在 bean 实例化之前允许开发者进行干预,例如返回不同的实例、应用代理等。它提供了一种高度的灵活性,可以用于一些特定的定制和场景,如实现懒加载、实现某种特定的单例模式、应用一些自定义的实例化逻辑等。

需要注意的是,使用 applyBeanPostProcessorsBeforeInstantiation 方法需要谨慎,因为它可以完全替代默认的实例化过程,可能会引入复杂性和不可预测的行为。在大多数情况下,通常不需要直接使用这个方法,而是通过其他 Spring 提供的功能来实现所需的定制。

postProcessBeforeInstantiation()方法的作用?
postProcessBeforeInstantiation 是 Spring Framework 中的一个回调方法,属于 InstantiationAwareBeanPostProcessor 接口的一部分。它在 Spring 容器实例化 bean 之前被调用,允许您在实例化过程中插入自定义的逻辑。这个方法的主要用途在于,您可以在 bean 实例化之前对要实例化的类类型进行检查或者在特定条件下返回一个不同的实例。这为您提供了在实例化 bean 之前进行一些特殊处理的机会,如返回代理对象、缓存对象、应用不同的子类等。
举个例子

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

public class CustomInstantiationProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        if (beanClass == MyBean.class && "myBeanName".equals(beanName)) {
            // Return a custom instance of MyBean
            return new CustomMyBean(); // You can return any instance you want
        }
        return null; // Proceed with regular instantiation
    }
}

在上面的示例中,我们实现了一个自定义的 InstantiationAwareBeanPostProcessor,并重写了 postProcessBeforeInstantiation 方法。在这个方法中,我们检查要实例化的类是否是 MyBean,并且要创建的 bean 的名称是否为 “myBeanName”。如果条件匹配,我们返回一个自定义的 CustomMyBean 实例,从而在实例化之前进行了定制。需要注意的是,如果您返回了非空实例,Spring 将跳过默认的实例化过程,直接使用您返回的实例。如果返回 null,则 Spring 将继续执行默认的实例化逻辑。这个方法可以用于各种场景,例如根据不同的条件返回不同的实例,进行实例的代理或者装饰,或者进行实例的预处理。但是,要小心不要滥用这个功能,以免造成复杂性和不可预测的行为。
再比如返回代理对象,举个例子

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

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyInstantiationProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        if (beanClass == UserServiceImpl.class) {
            return createProxy(UserServiceImpl.class);
        }
        return null; // Proceed with regular instantiation
    }

    private Object createProxy(Class<?> targetClass) {
        return Proxy.newProxyInstance(
            targetClass.getClassLoader(),
            new Class[]{UserService.class},
            new PermissionCheckingHandler(new UserServiceImpl())
        );
    }

    private static class PermissionCheckingHandler implements InvocationHandler {
        private final UserService target;

        public PermissionCheckingHandler(UserService target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // Perform permission checking logic here
            if (checkPermission()) {
                return method.invoke(target, args);
            } else {
                throw new SecurityException("Permission denied");
            }
        }

        private boolean checkPermission() {
            // Check permission logic
            return true; // For demonstration purposes
        }
    }
}

在这个示例中,我们实现了一个自定义的 InstantiationAwareBeanPostProcessor,并postProcessBeforeInstantiation 方法中返回了一个代理对象。代理对象使用 JDK 动态代理,代理了 UserServiceImpl 类,同时实现了 UserService 接口。代理对象的 invoke 方法中执行了权限检查,然后根据结果决定是否调用实际的方法。这种方法允许您在实例化 bean 之前对其进行定制,包括创建代理对象以实现横切关注点,如权限检查、日志记录等。请注意,这只是一个简化的示例,实际情况可能会更加复杂。

BeanPostProcessorsAfterInstantiation()方法的作用
和BeanPostProcessorsBeforeInstantiation()方法差不多,只不过是在实例化之后,属性注入之前进行的操作。
postProcessProperties()法的作用
让我们考虑一个示例:一个简单的权限管理系统中的用户对象。我们将在该方法中进行权限验证和动态注入属性。假设我们有一个用户类 User,其中包含用户的基本信息和角色信息。我们想要在初始化用户对象之前,根据用户角色动态注入不同的权限。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.stereotype.Component;

@Component
public class PermissionInjector implements InstantiationAwareBeanPostProcessor {

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (bean instanceof User) {
            User user = (User) bean;
            
            // 根据用户角色注入不同的权限
            if (user.getRole().equals("ADMIN")) {
                user.setPermissions("ALL_PERMISSIONS");
            } else if (user.getRole().equals("USER")) {
                user.setPermissions("READ_PERMISSION");
            }
        }
        return pvs;
    }
}

这个示例中,我们创建了一个名为 PermissionInjector 的类,实现了 InstantiationAwareBeanPostProcessor 接口。在 postProcessProperties() 方法中,我们检查了 Bean 是否为 User 类型,如果是,根据用户角色注入不同的权限。例如,如果用户角色是 “ADMIN”,则注入所有权限;如果用户角色是 “USER”,则只注入读取权限。

需要注意的是,postProcessProperties() 方法的返回值是 PropertyValues 对象,您可以对其进行修改,以修改属性的值。在此示例中,我们没有修改 PropertyValues,因此返回原始的值。

最后,在使用 Spring 容器创建和初始化 User 对象时,PermissionInjector 中的 postProcessProperties() 方法会被自动调用,根据用户角色注入不同的权限。

postProcessPropertyValues()方法的作用

postProcessPropertyValues 是 InstantiationAwareBeanPostProcessor 接口中的一个方法,用于在 Spring 容器进行属性注入之前对属性进行自定义操作。这个方法在 bean 的属性注入之前被调用,允许您修改、替换或添加属性的值

  1. pvs(PropertyValues):要应用于 bean 的属性值集合。这包含了将要注入到 bean 中的属性及其对应的值。
  2. pds(PropertyDescriptor[]):bean类中所有属性的属性描述符数组。属性描述符包含属性的名称、类型、读取方法和写入方法等信息。
  3. bean:正在被处理的 bean 实例。
  4. beanName:bean 的名称。
    在 postProcessPropertyValues 方法中对 pvs 进行操作,以实现对属性值的定制。例如,您可以根据属性的值来进行特定的修改,或者添加额外的属性。返回的 PropertyValues 对象可以是原始的 pvs 对象,也可以是经过修改后的新对象。
    以下是一个示例,展示了如何在 postProcessPropertyValues 方法中对属性值进行定制:
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

public class CustomPropertyProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        if (bean instanceof User && "userBean".equals(beanName)) {
            // Customize property values before injection
            MutablePropertyValues newPropertyValues = new MutablePropertyValues(pvs);
            
            PropertyValue usernameValue = newPropertyValues.getPropertyValue("username");
            if (usernameValue != null) {
                String username = (String) usernameValue.getValue();
                newPropertyValues.add("username", username.toUpperCase());
            }
            
            newPropertyValues.add("additionalProperty", "customValue");
            
            return newPropertyValues;
        }
        return pvs;
    }
}

在上面的示例中,CustomPropertyProcessor 类实现了 InstantiationAwareBeanPostProcessor 接口,并重写了 postProcessPropertyValues 方法。在这个方法中,我们检查要处理的 bean 是否是 User 类型,并且要处理的 bean 的名称是否为 “userBean”。如果条件匹配,我们使用 MutablePropertyValues 创建一个新的属性值集合,然后修改了 username 属性的值为大写字母,并添加了一个名为 additionalProperty 的额外属性。

这种方法允许您在属性注入之前对属性进行定制,以满足特定的需求。

populateBean()方法的作用
populateBean 方法是 Spring Framework 中的一个核心方法,用于将属性值填充到已实例化的 bean 实例中,完成属性的注入。它属于 AbstractAutowireCapableBeanFactory 类,是 Spring 容器中实现属性注入的重要部分。populateBean 方法用于将属性值填充到 bean 实例中,完成属性的注入。在 Spring 容器创建 bean 的过程中,当 bean 实例化完成后,它需要进行属性注入,以便将依赖关系和配置值传递给 bean。
执行过程:

  1. 获取 bean 的名称和 bean 的定义。 获取要填充的属性值集合,通常来自于 BeanDefinition 的属性值配置。
  2. 使用适当的 BeanWrapper 对象包装 bean 实例,以便可以访问和设置属性值。 遍历属性值集合,根据属性名称从
  3. BeanWrapper 中获取属性的 PropertyDescriptor,并设置属性值。
  4. 执行任何属性编辑器转换或类型转换,以确保属性值与属性类型兼容。 将属性值填充到 bean 实例中,完成属性注入。
    例如:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory {
    // ...

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        PropertyValues pvs = mbd.getPropertyValues();

        for (PropertyValue pv : pvs.getPropertyValues()) {
            String propertyName = pv.getName();
            Object originalValue = pv.getValue();
            Object convertedValue = getConvertedValue(originalValue, bw.getPropertyDescriptor(propertyName));

            bw.setPropertyValue(propertyName, convertedValue);
        }
    }
    
    private Object getConvertedValue(Object originalValue, PropertyDescriptor pd) {
        // Perform type conversion or other transformations if needed
        // Return the converted value
    }
}

在上面的示例中,populateBean 方法使用 PropertyValues 来获取要填充到 bean 实例中的属性值集合。然后,它使用 BeanWrapper 包装 bean 实例,通过遍历属性值集合,将属性值填充到 bean 实例中。在填充过程中,可能会进行属性编辑器转换或类型转换,以确保属性值的兼容性。populateBean 方法是 Spring 容器中用于属性注入的关键方法,它确保在 bean 创建过程中,将配置的属性值正确地填充到 bean 实例中,以满足依赖关系和定制需求。

postProcessBeforeInitialization()方法的作用
postProcessBeforeInitialization 是 Spring Framework 中的一个方法,属于 BeanPostProcessor 接口的一部分。它在 bean 初始化方法执行之前被调用,允许您在 bean 初始化之前应用自定义的逻辑。
方法的调用过程:

  1. 获取所有已注册的 BeanPostProcessor 对象。
  2. 遍历这些 BeanPostProcessor,依次调用它们的 postProcessBeforeInitialization 方法,传递 bean 的实例和 bean 的名称作为参数。
  3. 如果任何一个BeanPostProcessor 返回了非 null 值,那么返回的实例将作为初始化后的 bean实例,后续的初始化方法不会被执行;否则,继续执行后续的初始化方法。

示例:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof MyBean) {
            // Apply custom logic before initialization
            ((MyBean) bean).doSomethingBeforeInitialization();
        }
        return bean; // Continue with the original bean instance
    }
}

在上面的示例中,我们实现了一个自定义的 BeanPostProcessor,并重写了 postProcessBeforeInitialization 方法。在这个方法中,我们检查要处理的 bean 是否是 MyBean 类型,如果是的话,我们调用了 doSomethingBeforeInitialization 方法,以应用自定义的逻辑。然后,我们返回原始的 bean 实例,以继续后续的初始化过程。需要注意的是,postProcessBeforeInitialization 方法主要用于在 bean 初始化之前应用定制逻辑。如果您需要在 bean 初始化之后应用处理逻辑,可以使用 postProcessAfterInitialization 方法。

Aware接口的理解(标记作用)
ApplicationContextAwareProcessor#postProcessBeforeInitialization 首先判断此 bean 是不是各种的Aware,如果是它列举的那几个 Aware 就获取 Bean 工厂的权限,可以向容器中导入相关的上下文环境,目的是为了 Bean 实例能够获取到相关的上下文,如果不是它列举的几个 Aware,那就调invokeAwareInterfaces(bean),向容器中添加相关接口的上下文环境。

在 Spring 框架中的 bean 初始化过程中的一个步骤,具体来说是在 bean 初始化前的处理阶段,方法名为 postProcessBeforeInitialization。这个方法是在 Bean 初始化之前调用的一个扩展点,允许开发者在 Bean 初始化之前进行一些自定义的处理。在这个方法中,首先会判断当前的 Bean 是否实现了 Spring 的一些特定接口,比如 Aware 接口,这些接口包括 BeanFactoryAware、ApplicationContextAware 等。如果 Bean 实现了这些接口,它就会获得与容器相关的权限,可以获取到 Bean 工厂或者应用上下文,从而能够与容器进行交互。这些 Aware 接口的目的是为了让 Bean 能够获得它所在的上下文环境,以便进行一些操作或者获取一些资源。

如果 Bean 没有实现上述的 Aware 接口,那么在 postProcessBeforeInitialization 方法中会调用 invokeAwareInterfaces(bean),该方法会向容器中添加相关接口的上下文环境。这个步骤的目的是为了让 Bean 也能够通过接口方式获取到一些上下文环境。主要是 Spring 框架在 Bean 初始化前的一系列处理,主要是为了让 Bean 能够获得与容器相关的上下文环境,以便进行后续的操作。这是 Spring 框架中的一个重要的生命周期阶段,允许开发者在此阶段进行一些自定义的操作。
举个例子:
当你在使用 Spring 框架创建一个自定义的 Bean 时,你可能会需要在 Bean 初始化前获取到一些与容器相关的上下文环境。这时,你可以通过实现特定的 Aware 接口或者在 postProcessBeforeInitialization 方法中添加相应的逻辑来实现。举一个例子,假设你有一个名为 UserService 的 Bean,它需要在初始化前获取到应用程序上下文(ApplicationContext),以便在后续的操作中使用。你可以按照以下步骤实现:

public class UserService {
    private ApplicationContext applicationContext;

    // 在这里定义其他属性和方法

    public void doSomething() {
        // 在这里使用 applicationContext 进行操作
        // ...
    }
}

让 UserService 类实现 ApplicationContextAware 接口,并实现接口中的方法,这样你就能够获取到应用程序上下文。

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class UserService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    // 在这里定义其他属性和方法

    public void doSomething() {
        // 在这里使用 applicationContext 进行操作
        // ...
    }
}

在 UserService 类中,你可以在 doSomething 方法中使用 applicationContext 来获取一些上下文信息或者执行一些操作。

public void doSomething() {
    // 在这里使用 applicationContext 进行操作
    SomeOtherBean someOtherBean = applicationContext.getBean(SomeOtherBean.class);
    // 执行操作...
}

当 Spring 容器初始化 UserService Bean 时,由于 UserService 实现了 ApplicationContextAware 接口,Spring 会自动调用 setApplicationContext 方法,并将应用程序上下文传递给 UserService 对象。这样,在 doSomething 方法中就可以使用应用程序上下文来获取其他 Bean,执行一些操作,或者获取其他上下文信息。通过这个例子,你可以更好地理解在 Spring 中如何利用 Aware 接口和 postProcessBeforeInitialization 方法来获取与容器相关的上下文环境,以及如何在 Bean 初始化前进行自定义处理。

InitializingBean.afterPropertiesSet()
InitializingBean 是 Spring Framework 中的一个接口,用于在 Bean 初始化过程中执行特定的操作。它定义了一个方法 afterPropertiesSet(),在 Spring 容器创建 Bean 并设置了所有属性后,会自动调用该方法,允许开发者在此方法中执行自定义的初始化逻辑。当一个 Bean 实现了 InitializingBean 接口并且定义了 afterPropertiesSet() 方法时,Spring 容器会在以下情况下自动调用该方法:

  1. 在 Bean 创建后,将所有的属性设置完毕后。
  2. 在调用了所有的 postProcessBeforeInitialization 方法后。
    以下是一个示例,展示了如何使用 InitializingBean 接口来定义初始化逻辑:

当使用 InitializingBean 接口的 afterPropertiesSet() 方法时,让我们考虑一个简单的示例:一个订单处理系统中的订单对象。我们将在 afterPropertiesSet() 方法中进行属性验证和初始化。

import org.springframework.beans.factory.InitializingBean;

public class Order implements InitializingBean {

    private String orderId;
    private double amount;

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 在属性设置后执行初始化逻辑
        if (orderId == null || orderId.isEmpty()) {
            throw new IllegalArgumentException("Order ID cannot be null or empty.");
        }
        if (amount <= 0) {
            throw new IllegalArgumentException("Order amount must be greater than 0.");
        }
        // 执行其他初始化操作
        System.out.println("Order initialized: ID = " + orderId + ", Amount = " + amount);
    }
}

在这个示例中,Order 类实现了 InitializingBean 接口,并在 afterPropertiesSet() 方法中进行了属性验证和初始化操作。如果订单的ID为空或金额小于等于0,则会抛出异常。然后,在方法的最后,我们输出初始化的订单信息。

在使用该订单对象时,Spring 容器会在属性设置之后自动调用 afterPropertiesSet() 方法,以确保订单在被使用之前已经通过了验证并且具备正确的初始化状态。

postProcessAfterInitialization()方法
postProcessAfterInitialization 是 Spring 框架中一个用于扩展的回调方法,用于在 Bean 初始化之后执行自定义的逻辑。这个方法允许开发者在 Bean 初始化完成后对 Bean 进行进一步的处理或者添加自定义逻辑。

在 Spring 容器初始化 Bean 的过程中,postProcessAfterInitialization 方法会在每个 Bean 初始化完成后被调用,允许你在 Bean 初始化之后执行一些额外的操作。
举个例子,假设你有一个名为 LoggingService 的 Bean,你希望在它初始化完成后打印一条日志。你可以创建一个实现了 BeanPostProcessor 接口的类,然后在 postProcessAfterInitialization 方法中添加日志记录逻辑。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class LoggingBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 在 Bean 初始化完成后添加日志记录逻辑
        System.out.println("Bean '" + beanName + "' has been initialized.");
        return bean;
    }
}

然后,在 Spring 配置文件中,将这个自定义的 LoggingBeanPostProcessor 注册为一个 Bean:

<bean class="com.example.LoggingBeanPostProcessor" />

现在,每当 Spring 容器初始化一个 Bean 时,postProcessAfterInitialization 方法会被调用,并且你的日志记录逻辑会在每个 Bean 初始化完成后执行。

需要注意的是,postProcessAfterInitialization 方法的返回值通常是传入的 bean 参数本身,但你也可以对其进行修改(例如,包装成代理对象等),然后返回修改后的对象。

总之,postProcessAfterInitialization 方法允许你在 Spring 容器初始化 Bean 后执行自定义的逻辑,可以用于实现诸如日志记录、代理创建、监控等功能。

补充:PropertyValues类是什么
在 Spring Framework 中,pvs 是一个代表属性的容器,全称为 PropertyValues。它用于存储一个 bean 实例的属性及其对应的值,可以在属性注入过程中进行访问和操作。

PropertyValues 对象包含了一组 PropertyValue 对象,每个 PropertyValue 对象表示一个属性及其对应的值。属性的名称由字符串表示,属性的值可以是任何类型的对象。

在 Spring 的属性注入过程中,PropertyValues 会被用于存储要注入到 bean 实例中的属性值,以及可能在注入之前或之后进行修改的机会。

以下是一个简单示例,演示如何创建一个 PropertyValues 对象并添加属性值:

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;

// 创建一个 MutablePropertyValues 对象
MutablePropertyValues propertyValues = new MutablePropertyValues();

// 添加属性及其对应的值
propertyValues.add("username", "john_doe");
propertyValues.add("email", "john@example.com");

// 获取属性值
PropertyValue usernameValue = propertyValues.getPropertyValue("username");
String username = (String) usernameValue.getValue();

PropertyValue emailValue = propertyValues.getPropertyValue("email");
String email = (String) emailValue.getValue();

在 Spring 容器创建 bean 的过程中,PropertyValues 对象会被传递给 BeanFactory 或 ApplicationContext 中的相应实现,以完成属性的注入。在使用 InstantiationAwareBeanPostProcessor 接口的 postProcessPropertyValues 方法时,您可以获取并操作这个 PropertyValues 对象,以实现自定义的属性处理逻辑。
补充:MutablePropertyValues类是什么
MutablePropertyValues 是 Spring Framework 中的一个类,用于表示可变的属性值集合。它实现了 PropertyValues 接口,提供了一种方便的方式来管理属性及其对应的值,可以用于在 Spring 容器中进行属性的设置和修改。

通过 MutablePropertyValues,您可以创建一个属性值集合,然后逐个添加、修改或删除属性及其对应的值。这在处理属性注入、属性值定制以及一些自定义逻辑方面非常有用。

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;

// 创建一个 MutablePropertyValues 对象
MutablePropertyValues propertyValues = new MutablePropertyValues();

// 添加属性及其对应的值
propertyValues.add("username", "john_doe");
propertyValues.add("email", "john@example.com");

// 获取属性值
PropertyValue usernameValue = propertyValues.getPropertyValue("username");
String username = (String) usernameValue.getValue();

PropertyValue emailValue = propertyValues.getPropertyValue("email");
String email = (String) emailValue.getValue();

// 修改属性值
propertyValues.add("email", "updated@example.com");

// 删除属性
propertyValues.removePropertyValue("username");

// 判断是否包含某个属性
boolean containsEmail = propertyValues.contains("email");

// 获取所有属性的名称
String[] propertyNames = propertyValues.getPropertyNames();

MutablePropertyValues 可以在多个场景中使用,包括在 InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues 方法中,以及在手动创建和配置 bean 的过程中。它为属性值的设置和修改提供了一种灵活且可操作的方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/881418.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python爬虫——爬取天气预报信息

在本文中&#xff0c;我们将学习如何使用代理IP爬取天气预报信息。我们将使用 Python 编写程序&#xff0c;并使用 requests 和 BeautifulSoup 库来获取和解析 HTML。此外&#xff0c;我们还将使用代理服务器来隐藏我们的 IP 地址&#xff0c;以避免被目标网站封禁。 1. 安装必…

数据结构与算法-栈(LIFO)(经典面试题)

一&#xff1a;面试经典 1. 如何设计一个括号匹配的功能&#xff1f;比如给你一串括号让你判断是否符合我们的括号原则&#xff0c; 栈 力扣 2. 如何设计一个浏览器的前进和后退功能&#xff1f; 思想&#xff1a;两个栈&#xff0c;一个栈存放前进栈&…

【BERTopic应用 03/3】:微调参数

一、说明 一般来说&#xff0c;BERTopic 在开箱即用的模型中工作得很好。但是&#xff0c;当您有数百万个数据要处理时&#xff0c;使用基本模型处理数据可能需要一些时间。在这篇文章中&#xff0c;我将向您展示如何微调BERTopic中的一些参数并比较它们的结果。让我们潜入。 二…

简单学生信息管理系统springboot,ssm,ssh学生教师java jsp源代码

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 简单学生信息管理系统springboot,ssm,ssh 系统有1权限…

【C++】移动构造函数

2023年8月15日 概述 移动构造函数是一个特殊的构造函数&#xff0c;用于从一个对象中移动&#xff08;转移&#xff09;资源到另一个对象&#xff0c;而不是进行复制操作。它通常与右值引用一起使用&#xff0c;以实现高效的资源转移&#xff0c;提高性能。 语法 class MyCla…

操作系统-笔记-第二章

目录 二、第二章——【进程】 1、进程的概念 &#xff08;1&#xff09;PID & PCD 进程控制块 &#xff08;2&#xff09;程序段 & 数据段 &#xff08;3&#xff09;特征 &#xff08;特性&#xff09; property &#xff08;4&#xff09;总结 2、进程的状态 …

8个常用的项目管理工具和方法,干货收藏!

在现代商业环境中&#xff0c;高效的项目管理工具和方法是成功实施项目的关键。随着项目的规模和复杂性不断增加&#xff0c;需要科学的方法和先进的工具来确保项目按时交付、控制成本并保持质量。无论是项目管理新手还是经验丰富的专业人士&#xff0c;了解和掌握一些公认好用…

SCF金融公链新加坡启动会 创新驱动未来

新加坡迎来一场引人瞩目的金融科技盛会&#xff0c;SCF金融公链启动会于2023年8月13日盛大举行。这一受瞩目的活动将为金融科技领域注入新的活力&#xff0c;并为广大投资者、合作伙伴以及关注区块链发展的人士提供一个难得的交流平台。 在SCF金融公链启动会上&#xff0c; Wil…

【vue3】固定上导航栏和左侧导航栏,只显示其他内容在主内容区域

实现思路&#xff1a; 在一个单独的vue组件文件中只写出上导航栏和左侧导航栏的内容将你想要展示的页面主内容写到单独的组件中在index.js写路由&#xff0c;将【想要展示的页面主内容的路由】作为【子路由】写在【只写出上导航栏和左侧导航栏的路由】的下面&#xff1b; 在el…

一百五十二、Kettle——Kettle9.3.0本地连接Hive3.1.2(踩坑,亲测有效,附截图)

一、目的 由于先前使用的kettle8.2版本在Linux上安装后&#xff0c;创建共享资源库点击connect时页面为空&#xff0c;后来采用如下方法&#xff0c;在/opt/install/data-integration/ui/menubar.xul文件里添加如下代码 <menuitem id"file-openZiyuanku" label&…

七夕特辑:所以结婚到底有什么好处?

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 伊姐 运营 / SandLiu 卷圈 监制 / 姝琦 封面 / 姝琦Midjourney 产品统筹 / bobo 场地支持 / 声湃轩天津录音间 七夕来临&#xff0c;“记者下班”第一次和大家聊聊亲密关系。 无论是青梅竹马、相识二十年的阿福&#…

私有IP地址有多重要?

私有IP地址是指在局域网中使用的IP地址&#xff0c;而不是公共互联网上可访问的IP地址。私有IP地址不唯一&#xff0c;可以在不同的局域网中重复使用。这种地址分配方式能够有效地节省IP地址资源。 近日&#xff0c;国际互联网协会&#xff08;IATA&#xff09;发布了一项关于私…

twinmotion和lumion相比选哪个更好?

建筑和室内可视化软件彻底改变了设计行业。随着实时渲染技术的引入&#xff0c;建筑师和设计师现在可以在几分钟内创建其设计的逼真渲染。Twinmotion 和 Lumion 是近年来流行的两个这样的程序。在本文中&#xff0c;我们将比较这两种引擎 - 它们有何不同&#xff0c;以及针对特…

恒运资本:CPO概念发力走高,兆龙互联涨超10%,华是科技再创新高

CPO概念15日盘中发力走高&#xff0c;截至发稿&#xff0c;华是科技涨超15%再创新高&#xff0c;兆龙互联涨逾11%&#xff0c;中贝通讯涨停&#xff0c;永鼎股份、太辰光涨超5%&#xff0c;天孚通讯涨逾4%。 消息面上&#xff0c;光通讯闻名咨询机构LightCounting近日发布的202…

【从零学习python 】30.深入理解递归函数和匿名函数

文章目录 递归函数1. 什么是递归函数2. 递归函数的作用解决办法1: 使用循环来完成解决办法2: 使用递归来实现 匿名函数应用场合函数作为参数传递练习进阶案例 递归函数 1. 什么是递归函数 通过前面的学习知道一个函数可以调用其他函数。 如果一个函数在内部不调用其它的函数…

高效的Python隧道代理配置与管理

作为一名专业爬虫程序员&#xff0c;我们需要掌握高效的Python隧道代理配置与管理&#xff0c;以提高爬取数据的效率并保护个人隐私安全。本文将分享从入门到精通的Python隧道代理配置与管理技巧&#xff0c;为大家提供实用的操作指南和专业的知识分享。让我们一起步入高效的Py…

垒球发展史·棒球1号位

垒球发展史 1. 垒球起源与初始阶段 垒球运动的起源 垒球运动&#xff0c;诞生于十九世纪末&#xff0c;起初只是为了娱乐消遣而逐渐发展成一项竞技运动。在十九世纪晚期&#xff0c;美国开始流行一种叫做“篮球弹”的游戏&#xff0c;它的游戏规则与现在的垒球十分相似&#…

集水井、PE集水井、雨水渗透井、环保渗透井、渗透式雨水口

城市道路与开放空间形成的雨水表面径流&#xff0c;是许多城市化地区面源水污染的重要来源。水流流过的不透水表面&#xff0c;会将道路、停车场、草坪等表面的垃圾、油污、重金属、化肥、农药等污染物带入水体。如直接排放&#xff0c;容易造成河流、溪水污染&#xff0c;最终…

【Vue-Router】历史记录

replace App.vue <template><h1>hello world</h1><div><!-- replace 不保存历史记录 --><router-link replace to"/">login</router-link><router-link replace style"margin-left: 10px;" to"/reg&q…

响应式设计是什么?怎么学习? - 易智编译EaseEditing

响应式设计是一种用于创建能够适应不同设备和屏幕尺寸的网站和应用程序的设计方法。它的目标是确保网站在各种设备上都能提供良好的用户体验&#xff0c;无论是在大屏幕的桌面电脑上还是在小屏幕的移动设备上。 在响应式设计中&#xff0c;页面的布局、字体、图像和其他元素会…