在 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;
    }





}
相关推荐
一只小bit1 小时前
Redis哨兵机制、主从复制与集群搭建与维护
数据库·redis·bootstrap
zlwool7 小时前
图纸管理选型避坑指南
数据库·erp·设备erp·非标机械
小灰灰搞电子9 小时前
完全驾驭 Qt 与数据库:C++ ORM 框架 QxOrm 原理与实践指南
数据库·c++·qt
2601_961901709 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
软件聚导航10 小时前
「聚小软 AI 助手」技术升级:从数据库检索到 RAG 知识库问答
前端·数据库·mysql·微信小程序·小程序·ai编程·rag
学习星球11 小时前
单调栈——从“找下一个更大的“到柱状图中的最大矩形
数据库·c++·算法·leetcode·xcode
GoppViper11 小时前
RDF资源描述框架深度解析:语义Web的数据基石与实战逻辑
前端·数据库
2601_9621741712 小时前
Redis 简介
数据库·redis·wpf
专注仿真12 小时前
Spring AI 实现智能对话系统项目指南
数据结构·spring·机器学习
夜雪一千12 小时前
MySQL 各种数据同步方案全梳理:从简单复制到异构同步实战
数据库·mysql