解决SpringBoot中自己new出来的对象不能自动注入对象和属性的问题

本文介绍如何在Spring框架中使用自定义工具类GetBeanUtil进行Bean的管理和注入,以及如何通过GetPropertiesUtil工具类解决自定义类中属性的注入问题。详细展示了如何在未被Spring管理的类中获取Spring管理的Bean实例,以及如何在这些类中正确注入配置文件中的属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

鉴于大家留言中指出的所有错误问题,现在我把公司里的源代码贴出来供大家参考:

 懒得看解释的,直接用这个类即可:      

@Component
public class GetBeanUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (GetBeanUtil.applicationContext == null) {
            GetBeanUtil.applicationContext = applicationContext;
        }
    }

    /**
     * 返回ApplicationContext
     *
     * @return ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 返回bean
     *
     * @param beanName beanName
     * @return bean
     */
    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }

    /**
     * 获取bean
     *
     * @param c c
     * @param <T> 泛型
     * @return bean
     */
    public static <T> T getBean(Class<T> c) {
        return applicationContext.getBean(c);
    }

    /**
     * 获取bean
     * @param c c
     * @param  name 名称
     * @param <T> 泛型
     * @return T 泛型
     */
    public static <T> T getBean(String name, Class<T> c) {
        return getApplicationContext().getBean(name, c);
    }
}

使用方法:

public class AreaInvadeAnalyzer extends Analyzer {

    private AreaInvadeMapper areaInvadeMapper =GetBeanUtil.getBean(AreaInvadeMapper.class);

    ....其他代码省略

}

-----------------------------------------------------------------------------------------------------------------------下面旧文可以不看------------------------------------------------------------------------------------------------------------------------------------------------

在类上加@Component或者其他注解时,该类会交给spring来管理,自动创建对象,但是如果是自己new出来的对象或者自己类没加注解,但是内部又需要注入其他对象以及需要注入配置文件中的属性时,有以下办法解决:

1、解决注入对象问题:

新建一个工具类,比如GetBeanUtil

public class GetBeanUtil implements ApplicationContextAware {
    protected static ApplicationContext context;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);//name表示其他要注入的注解name名
    }

    public static <T> T getBean(T c){

        return applicationContext.getBean(c);//T表示类
    }
}

举例使用上述工具类:

public MyClass
{
    @AutoWired
    private OtherClass otherClass;
}

上面类在new MyClass时,OtherClass类注入会失败,此时改进一下情况即可:(注意,OtherClass必须是spring注解过的)

public MyClass
{
    private OtherClass otherClass = GetBeanUtil.getBean(OtherClass.class);
}

简单解释一下工具类为什么能够找到类,是因为在启动spring后,spring会将所有注解过的类加载容器内,并返回 给ApplicationContextAware,在其他注解后的类需要对象时,容器会自动注入,但是自己new的类缺不会被容器注入,此时,自己实现ApplicationContextAware,自己根据类的类型手动获得加载后的bean即可。

2、解决注入属性问题

创建一个工具类:

@Component//注意此时要加注解
public class GetPropertiesUtil
{
    
    private static String properties;
    
    public static Stirng getProperties()
    {    
        return properties;
    }
    @Value("${properties}")
    public void setProperties(String properties)
    {
        this.properties = proterties;
    }
}

注意两点:1、该工具类要加上注解,否则会像第一种情况;

                  2、内部属性加@Value的地方是set方法上,而且set方法不是statis;

 

使用举例:

public MyClass
{
    @Value("${properties}")
    private String properties;
}

上面类在new MyClass时,xxx属性注入会失败,此时改进一下情况即可:

public MyClass
{
    private String properties = GetPropertiesUtil.getProperties();
}

 

<think>好的,用户的问题是在Spring Boot中,如何在通过配置文件注入对象之前对数据进行预处理。首先,我需要回忆一下Spring Boot的配置处理流程。用户提到的是注入对象前的预处理,所以应该是在属性被绑定到对象之前进行处理。 首先想到的是,Spring Boot使用@ConfigurationProperties来注入配置到对象中。那么在数据绑定之前,可能需要对配置值进行修改或验证。这时候,我需要考虑是否有相关的机制可以在属性绑定前进行处理。 记得Spring Boot有@PostConstruct注解,但这是在对象创建之后执行的,可能不符合用户的需求,因为用户希望在注入前处理数据。另外,可能可以使用EnvironmentPostProcessor接口,它允许在应用上下文初始化之前修改环境属性。不过这个需要自定义实现,并注册到spring.factories中。 还有一种方法是使用@ConfigurationPropertiesBinding,自定义Converter或者PropertyEditor,将配置文件中的字符串转换为目标类型时进行处理。例如,如果配置中的某个值需要解密,可以编写一个Converter来自动解密后再绑定到属性上。 另外,用户提到的预处理可能包括数据验证,这时候可以使用JSR-303的注解如@Validated,但这属于绑定后的验证,不是预处理。不过结合自定义的转换器,可能可以达到预处理的效果。 还需要考虑是否在配置类中使用@Bean方法,在创建Bean之前进行预处理。例如,在@Bean方法中读取配置值,处理后再创建对象。但这样可能不如使用@ConfigurationProperties方便,尤其是当配置结构复杂时。 查阅引用中的内容,引用[3]提到了使用Filter进行请求过滤,可能配置预处理无关。引用[2]提到Spring Data Redis中的Operations接口,可能也不相关。引用[4]关于Thymeleaf配置,但用户问题集中在配置注入前的处理。引用[1]提到@SpringBootConfiguration,属于配置类的注解,但未直接涉及预处理。 综合起来,可能的解决方案包括: 1. 自定义Converter,通过@ConfigurationPropertiesBinding注册,在转换时处理数据。 2. 实现EnvironmentPostProcessor,提前修改环境中的属性值。 3. 在@ConfigurationProperties类中使用@PostConstruct方法,但这可能是在注入之后处理,不是之前。 4. 使用Spring Boot的Binder API,在绑定前进行自定义处理。 其中,方法12可能更符合用户的需求。需要详细说明这两种方法的实现步骤,并提供代码示例。 另外,用户可能希望在不修改配置类的情况下进行预处理,或者希望全局处理某些类型的配置值。例如,解密敏感信息或格式化字符串。 需要确保回答的结构清晰,分步骤说明每种方法,并引用相关Spring Boot的机制。同时,根据用户提供的引用,可能可以结合其中的注册方式,比如使用FilterRegistrationBean类似的注册方式来处理预处理逻辑,不过这可能不适用。 最后,检查是否有遗漏的其他方法,例如使用BeanFactoryPostProcessor或BeanPostProcessor,但这些可能影响更广泛的Bean生命周期,需要谨慎使用。 总结,主要解决方案是自定义转换器EnvironmentPostProcessor,这两种方法较为直接且符合Spring Boot的扩展机制。</think>在Spring Boot中,在通过配置文件注入对象前进行数据预处理,可通过以下方法实现: ### 一、使用`@ConfigurationPropertiesBinding`自定义转换器 1. **定义数据转换器** 创建实现`Converter<String, T>`接口的类,在转换过程中插入预处理逻辑: ```java public class EncryptedStringConverter implements Converter<String, String> { @Override public String convert(String source) { return decrypt(source); // 示例:对加密字段解密 } } ``` 2. **注册转换器** 在配置类中使用`@ConfigurationPropertiesBinding`注解绑定到Spring容器: ```java @Configuration public class ConverterConfig { @Bean @ConfigurationPropertiesBinding public EncryptedStringConverter encryptedStringConverter() { return new EncryptedStringConverter(); } } ``` 3. **配置类声明** 通过`@ConfigurationProperties`注入预处理后的值: ```java @ConfigurationProperties(prefix = "app") public class AppConfig { private String secretKey; // 注入时会自动解密 } ``` ### 二、通过`EnvironmentPostProcessor`修改原始配置 1. **实现接口** 创建类实现`EnvironmentPostProcessor`,在配置加载阶段修改属性: ```java public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor { @Override public void postProcessEnvironment( ConfigurableEnvironment env, SpringApplication app) { String rawValue = env.getProperty("app.db.url"); env.getPropertySources().addFirst( new MapPropertySource("custom", Collections.singletonMap("app.db.url", process(rawValue)) )); } } ``` 2. **注册扩展** 在`src/main/resources/META-INF/spring.factories`中添加: ```properties org.springframework.boot.env.EnvironmentPostProcessor=com.example.CustomEnvironmentPostProcessor ``` ### 三、结合`BeanFactoryPostProcessor`动态修改配置 ```java public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { PropertySourcesPlaceholderConfigurer configurer = beanFactory.getBean(PropertySourcesPlaceholderConfigurer.class); // 通过MutablePropertySources修改属性值 } } ``` ### 四、数据验证型预处理 使用JSR-303规范结合自定义约束: ```java @Validated @ConfigurationProperties(prefix = "service") public class ServiceConfig { @Pattern(regexp = "^https?://.*") private String endpoint; // 自动校验格式 } ``` ### 方法对比 | 方法 | 执行阶段 | 适用场景 | |--------------------------|-------------------|------------------------------| | 自定义转换器 | 属性绑定阶段 | 类型转换/格式化/解密 | | EnvironmentPostProcessor | 环境准备阶段 | 全局配置修改/环境变量覆盖 | | BeanFactoryPostProcessor | Bean定义加载阶段 | 复杂属性源动态调整 | | 数据验证 | 属性绑定后 | 格式校验/业务规则检查 | [^1]: Spring Boot通过`@ConfigurationPropertiesBinding`机制支持自定义类型转换逻辑。 [^2]: 预处理方法需与Spring Boot的生命周期阶段匹配才能生效。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值