java - 使用反射加载随机类并将其注册为 springboot 中的组件

标签 java spring spring-boot

我在随机包中有一个随机类,在应用程序启动后通过反射加载,有没有办法让它在springboot下注册为组件并具有@Autowired等注释和 @Value 等适用于该类。

当它在启动时位于同一个包中时它可以工作,但是如果在运行时通过另一个jar引入它(无论是否相同的包)它就不起作用。

下面的示例即使在同一个 jar 中也不起作用。我无法更改应用程序的配置 - 它会破坏“随机包/随机类”目标。

Spring boot应用程序包中的代码

package sample.app
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        // Code that starts app
        //
        //
        try {
            Thread.sleep(7000);
            Class test = Class.forName("test.Test", true, Application.class.getClassLoader());
            System.out.println(test.getMethod("getName").invoke(null));     //NPE
            System.out.println(test.getMethod("getProfiles").invoke(null)); //NPE
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

测试.java

package test;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;

@DependsOn("blaaaaaaaah")
@ComponentScan
public class Test {

    @DependsOn("blaaaaaaaah")
    public static String getName() {
        return SpringGetter.instance.getApplicationName();
    }

    @DependsOn("blaaaaaaaah")
    public static String[] getProfiles() {
        String[] profiles = SpringGetter.instance.getEnv().getActiveProfiles();
        if (profiles == null || profiles.length == 0) {
            profiles = SpringGetter.instance.getEnv().getDefaultProfiles();
        }
        return profiles;
    }

}

SpringGetter.java

package test;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Component("blaaaaaaaah")
public class SpringGetter implements InitializingBean {
    public static SpringGetter instance;

    @Value("${spring.application.name}")
    private  String applicationName;
    @Autowired
    private Environment env;

    public SpringGetter() {
        System.out.println("consASFJEFWEFJWDNFWJVNJSBVJWNCJWBVJNVJNVJSNJSNCSDJVNSVJtruct");
    }

    public String getApplicationName() {
        return applicationName;
    }

    public void setApplicationName(String applicationName) {
        this.applicationName = applicationName;
    }

    public Environment getEnv() {
        return env;
    }

    public void setEnv(Environment env) {
        this.env = env;
    }

    @PostConstruct
    public void setInstance() {
        instance = this;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        instance = this;
    }
}

编辑: 我设法动态创建 SpringGetter 类,作为与 Application 类(带有 @SpringBootApplication 的包)相同的包的一部分。我让 Test.java 指向该动态类,但没有成功。

最佳答案

要简单地将字段注入(inject)到 POJO 中,就好像它是 Spring 管理的 bean 一样,您可以使用如下所示的内容:

@Component
public class BeanInitializer implements ApplicationContextAware {

  private AutowireCapableBeanFactory beanFactory;

  @Override
  public void setApplicationContext(final ApplicationContext applicationContext) {
      beanFactory = applicationContext.getAutowireCapableBeanFactory();
  }

  public void initializeObject(Object pojo) {
      beanFactory.autowireBean(pojo);
  }
}

请注意,但是,这注入(inject)标记为@Autowired@Injected的字段。它不会创建遵循基于例如方法拦截策略的代理。 @Transactional@Async

关于java - 使用反射加载随机类并将其注册为 springboot 中的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60235031/

相关文章:

java - java swing 中的电话号码验证

java - 如何将句子输入到HashMap中

java - 使用jSTL核心迭代json值时出现异常

java - Eclipse:Spring Explorer 不显示使用 Java 文件配置的 beans

spring - 使用 Spring Data Graph/Neo4j 进行分页

java - 将 arraylist 中的每个值显示到每个 textView Android

java - HttpURLConnection - 未知格式(魔数(Magic Number) 376)

spring - 用于yml或属性的Spring Cloud Config Brixton.M5 HTTP 406

elasticsearch - Spring Data ElasticSearch 无法与 ElasticSearch 5.5.0 连接

java - Spring Boot - POST 请求方法不起作用,但 GET 起作用