背景:我们之前项目用的自己研发的框架,后来又要重构,但是有些功能还依赖于之前的框架,万不得已的情况下,我就把之前的框架当成三方的依赖给引入,引入以后就发现,很多类上用了@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;
}
}