在 Spring 容器初始化 Bean 时,通过反射机制处理带有自定义 注解的字段,并将其注入相应的 Spring 管理的 Bean

背景:我们之前项目用的自己研发的框架,后来又要重构,但是有些功能还依赖于之前的框架,万不得已的情况下,我就把之前的框架当成三方的依赖给引入,引入以后就发现,很多类上用了@Inject这个注解,再一看包名竟然是自定义的,这几个类就是无法注入到spring中,用了好多种方法,使用的时候永远null,

话不多说,直接上代码

java 复制代码
package com.pj.atomarrowSy.processor;

import net.atomarrow.annotation.Inject;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * 处理器的作用:
 * 在 Spring 容器初始化 Bean 时,
 * 通过反射机制处理带有自定义注解 @Inject 的字段,
 * 并将这些字段注入相应的 Spring 管理的 Bean。
 * implements BeanPostProcessor:实现 BeanPostProcessor 接口,允许在 Bean 初始化前后进行自定义处理
 * implements ApplicationContextAware:实现 ApplicationContextAware 接口,使得该类可以获取到当前的 ApplicationContext,从而能够访问 Spring 容器中的其他 Bean。
 */
@Component
public class CustomInjectAnnotationBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware{
    private ApplicationContext applicationContext;

    //在 Bean 初始化之前调用的方法。
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        // 遍历 Bean 中的所有字段
//        System.out.println("Processing bean: " + beanName);
        for (Field field : bean.getClass().getDeclaredFields()) {
            if (field.isAnnotationPresent(Inject.class)) { //检查字段是否有 @Inject 注解
                System.out.println("Found @Inject annotation on field: " + field.getName() + " in class: " + bean.getClass().getName());
                try {
                    field.setAccessible(true);// 设置字段可访问
                    Object fieldValue = applicationContext.getBean(field.getType()); // 从 Spring 容器中获取相应类型的 Bean
                    if (fieldValue == null) {
                        System.err.println("Bean not found in context for type: " + field.getType().getName() + " in class: " + bean.getClass().getName());
                    } else {
                        field.set(bean, fieldValue);// 将获取到的 Bean 注入到字段中
                        System.out.println("Injected field: " + field.getName() + " with value: " + fieldValue + " in class: " + bean.getClass().getName());
                    }
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("Failed to inject field: " + field.getName() + " in class: " + bean.getClass().getName(), e);
                }
            }
        }
        return bean; // 返回处理后的 Bean
    }
    //在 Bean 初始化之后调用的方法。这里没有做任何额外处理,直接返回 Bean。
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        // 这里不需要做额外的处理
        return bean;
    }
    //实现 ApplicationContextAware 接口的方法,
    // 用于设置 ApplicationContext,使 CustomInjectAnnotationBeanPostProcessor 能够访问 Spring 容器中的 Bean。
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }





}
相关推荐
Edingbrugh.南空1 小时前
Flink SQLServer CDC 环境配置与验证
数据库·sqlserver·flink
码不停蹄的玄黓1 小时前
MySQL分布式ID冲突详解:场景、原因与解决方案
数据库·分布式·mysql·id冲突
爱上语文2 小时前
Redis基础(6):SpringDataRedis
数据库·redis·后端
Java初学者小白2 小时前
秋招Day14 - Redis - 应用
java·数据库·redis·缓存
丶意冷3 小时前
mybatisPlus分页方言设置错误问题 mybatisPlus对于Oceanbase的Oracle租户分页识别错误
java·数据库·oracle·oceanbase
要开心吖ZSH4 小时前
《Spring 中上下文传递的那些事儿》Part 4:分布式链路追踪 —— Sleuth + Zipkin 实践
java·分布式·spring
考虑考虑4 小时前
Springboot3.4.x中的@Bean使用
spring boot·后端·spring
时序数据说5 小时前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
戒不掉的伤怀5 小时前
【Navicat 连接MySQL时出现错误1251:客户端不支持服务器请求的身份验证协议;请考虑升级MySQL客户端】
服务器·数据库·mysql
cv高级工程师YKY5 小时前
服务器 - - QPS与TPS介绍
数据库