当前位置: 首页 > 知识库问答 >
问题:

在Spring ApplicationContext加载之后,有没有办法扫描所有@Component类的注释类

颜瀚漠
2023-03-14

我想在加载ApplicationContext后将@Component类添加到spring容器中。但我不能使用BeanFactory。因为我使用的是BeanFactory,所以我必须为这些类定义bean。但是我不能定义它(如果我不使用反射)。因为这些类将在运行时由类加载器加载。

例如

@Component
public class Service {

    private final CustomerService customerService;
    private final OrderService orderService;
    private final PaymentService paymentService;

    @Autowired
    public Service(CustomerService customerService, OrderService orderService, PaymentService paymentService) {
        this.customerService = customerService;
        this.orderService = orderService;
        this.paymentService = paymentService;
    }
}

在本例中,Spring在应用程序调用时为此类创建bean。没有必要用@Bean来定义bean。但是我想要的是编译Spring项目,并从另一个项目加载这些类,并添加到Spring Application ationContext中。所以我可以自动连接这些。否则,我必须在运行时创建带有反射的bean。如果我使用反射,我将递归调用所有依赖类。

有没有办法不在运行时使用反射创建bean就可以做到这一点。

共有2个答案

公西财
2023-03-14

我找到了解决办法。

    ConfigurableApplicationContext context = SpringApplication.run(EventServiceApplication.class, args);
    // Load class ...
    context.start();

若我们在load类之后运行context.start()方法,spring将创建@Component类bean并放入spring容器。

另一种解决方案(这是精确的解决方案):

ConfigurableApplicationContext context = SpringApplication.run(EventServiceApplication.class, args);

List<Class<?>> classes = // load classes

classes
.stream()
.filter(clazz -> clazz.isAnnotationPresent(Component.class) || Arrays.stream(clazz.getAnnotations()).anyMatch(annotation -> annotation.annotationType().isAnnotationPresent(Component.class)))
.forEach(applicationContext::register);

在注册类之后,您加载的类中可能有一个用@Configuration注释,并且它包含@Bean注释的方法。注册那些@Bean方法。你应该使用

ConfigurationClassPostProcessor configurationClassPostProcessor; // This class is autowireable. Spring has bean for this class at spring bean container.
configurationClassPostProcessor.processConfigBeanDefinitions(applicationContext.getDefaultListableBeanFactory())

我在Spring框架源代码中找到了这个解决方案

傅琦
2023-03-14

如果我理解正确:您有一些用@Component标记的类,您希望Spring管理它们的生命周期

这有帮助吗:https://springframework.guru/spring-component-scan/?@ComponentScan具体地或在XML配置类似的东西:

 <context:component-scan base-package="org.example"/>
 类似资料:
  • 我正试着写这段代码 我尝试了许多方法来修复它,但都不起作用:(

  • 问题内容: 我的PC上没有太多内存,处理器也很弱。尽管到目前为止,netbeans是我最喜欢的IDE,但在我现有的计算机上使用它几乎是难以忍受的,因为打开程序时,项目扫描会自动开始。 有没有办法防止Netbeans扫描项目? 问题答案: 嗨,乔治,我不知道这是否是答案,但是我右键单击并在不需要打开的项目上选择“关闭”。将您过去的所有项目都列出在那里是没有意义的。只需将您正在开发的那个打开。您始终可

  • 问题内容: 在我不使用Spring的项目中,我仅使用Hibernate。我不想将hbm.xml文件用于实体映射/描述/等。我只想使用注释。 如何告诉Hibernate 从某些包中加载所有带注释的类? 我在网上搜索,但没有运气。我也找不到有关最新的Hibernate版本的信息(大多数是过时的文章/帖子/等)。 编辑1: http://docs.jboss.org/hibernate/orm/4.3/

  • 问题内容: 在我从事的项目中,我不使用Spring,而仅使用Hibernate。我不想将hbm.xml文件用于实体映射/描述/等。我只想使用注释。 如何告诉Hibernate 从某些包中加载所有带注释的类? 我在网上搜索,但没有运气。我也找不到有关最新的Hibernate版本的信息(大多是过时的文章/帖子/等)。 编辑1: http://docs.jboss.org/hibernate/orm/4

  • 问题内容: 我正在尝试为旧框架实施一些单元测试。我正在尝试模拟数据库层。不幸的是,我们的框架有些陈旧,没有很好地使用最佳实践,因此没有明确的关注点分离。我有点担心尝试模拟数据库层可能会使JVM加载大量甚至无法使用的类。 我不太了解类加载器,所以这可能不是问题。是否有办法在一个特定的ClassLoader加载的所有类中发挥最大作用,以证明引擎盖下发生了什么? 问题答案: 警告使用 将产生巨大的产出。

  • 所以我想要一个“Void Repository”,通过它可以访问不一定在实体上操作的存储过程。 但这当然不起作用,因为期望是一个实体。 有没有一种方法可以使用注释而无需创建虚拟实体,或者我是否坚持使用使用通过准备好的语句进行查询的已实现类? 因为老实说,这很难看: