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





}
相关推荐
xujiangyan_1 小时前
Redis详解
数据库·redis·缓存
Y编程小白4 小时前
PostgreSQL在Linux中的部署和安装教程
数据库·postgresql
TiAmo zhang6 小时前
SQL Server 2019实验 │ 数据库和表的创建、修改与删除
数据库·oracle
disanleya7 小时前
MySQL默认密码不安全?如何首次登录并强化?
数据库·mysql·安全
花开富贵贼富贵7 小时前
MySQL 核心高级特性
运维·数据库·mysql
hello 早上好7 小时前
深入 Spring 依赖注入底层原理
数据库·sql·spring
API快乐传递者7 小时前
抓取淘宝商品详情商品数据API接口调用说明文档|获取淘宝商品价格主图数据等
数据库
济南java开发,求内推7 小时前
Redis一个服务器部署多个节点
服务器·数据库·redis
花菜会噎住7 小时前
Django视图与路由全解析:从URL到页面,一篇讲透
数据库·django·sqlite·函数
-雷阵雨-8 小时前
MySQL——数据库约束
数据库·mysql