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





}
相关推荐
云和数据.ChenGuang40 分钟前
Django 应用安装脚本 – 如何将应用添加到 INSTALLED_APPS 设置中 原创
数据库·django·sqlite
woshilys1 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
Hacker_LaoYi1 小时前
SQL注入的那些面试题总结
数据库·sql
建投数据2 小时前
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
数据库·腾讯云
Hacker_LaoYi3 小时前
【渗透技术总结】SQL手工注入总结
数据库·sql
岁月变迁呀3 小时前
Redis梳理
数据库·redis·缓存
独行soc3 小时前
#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍06-基于子查询的SQL注入(Subquery-Based SQL Injection)
数据库·sql·安全·web安全·漏洞挖掘·hw
你的微笑,乱了夏天4 小时前
linux centos 7 安装 mongodb7
数据库·mongodb
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
工业甲酰苯胺4 小时前
分布式系统架构:服务容错
数据库·架构