Spring @Configuration注解示例

x33g5p2x  于2022-10-06 转载在 Spring  
字(2.8k)|赞(0)|评价(0)|浏览(705)

在这篇文章中,我们将讨论一个非常重要的基于Spring Java的配置注解,即a@Configurationannotation,并附有实例。

Spring @Configuration注解是Spring核心框架的一部分。Spring配置注解表明该类有@Bean定义方法。因此,Spring容器可以处理该类并生成Spring Bean,以便在应用程序中使用。

@Configuration注解概述

@Configuration是一个类级注解,表示一个对象是Bean定义的来源。@Configurationclasses通过公共的@Bean注解方法声明Bean。对@Bean方法的调用on@Configurationclasses也可以用来定义bean间的依赖关系。

Spring Boot更倾向于基于Java的配置。虽然可以使用SpringApplication与XML来源,但Spring Boot社区一般建议我们的主要来源是一个@Configuration类。通常,定义main方法的类是作为主要@Configuration的良好候选。
**提示:**互联网上已经发布了许多使用XML配置的Spring配置实例。如果可能的话,总是尝试使用基于Java的等效配置。搜索Enable*注解可以作为一个好的起点。

导入额外的配置类 

你不需要把所有的@Configuration放到一个单一的类中。可以使用@Import注解来导入额外的配置类。另外,你可以使用@ComponentScan来自动拾取所有Spring组件,包括@Configuration类。

阅读更多关于Spring的@Import注解 @Import注解与实例

导入XML配置

如果你使用了基于XML的配置,那么你可以使用@ImportResource注解来加载XML配置文件。

了解更多关于Spring @PropertySource注解实例的@ImportResource注解的信息

下面的图显示了一个内部实现,供你参考。

最简单的@Configurationclass的内容如下。

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.context.annotation.Bean;
  3. import org.springframework.context.annotation.Configuration;
  4. import com.companyname.projectname.customer.CustomerService;
  5. import com.companyname.projectname.order.OrderService;
  6. @Configuration
  7. public class Application {
  8. @Bean
  9. public CustomerService customerService() {
  10. return new CustomerService();
  11. }
  12. @Bean
  13. public OrderService orderService() {
  14. return new OrderService();
  15. }
  16. }

上面的AppConfigclass将等同于下面的Spring XML。

  1. <beans>
  2. <bean id="customerService" class="com.companyname.projectname.CustomerService"/>
  3. <bean id="orderService" class="com.companyname.projectname.OrderService"/>
  4. </beans>

注入bean间的依赖关系

@Bean之间有依赖关系时,表达这种依赖关系就像让一个bean方法调用另一个一样简单。

  1. @Configuration
  2. public class AppConfig {
  3. @Bean
  4. public Foo foo() {
  5. return new Foo(bar());
  6. }
  7. @Bean
  8. public Bar bar() {
  9. return new Bar();
  10. }
  11. }

在上面的例子中,foo Bean通过构造函数注入接收对bar的引用。

###基于Java的配置在内部是如何工作的?

下面的例子显示一个@Bean注解的方法被调用了两次。

  1. @Configuration
  2. public class AppConfig {
  3. @Bean
  4. public ClientService clientService1() {
  5. ClientServiceImpl clientService = new ClientServiceImpl();
  6. clientService.setClientDao(clientDao());
  7. return clientService;
  8. }
  9. @Bean
  10. public ClientService clientService2() {
  11. ClientServiceImpl clientService = new ClientServiceImpl();
  12. clientService.setClientDao(clientDao());
  13. return clientService;
  14. }
  15. @Bean
  16. public ClientDao clientDao() {
  17. return new ClientDaoImpl();
  18. }
  19. }

clientDao()在inclientService1()clientService2()中被调用了一次。由于这个方法创建了一个ClientDaoImpl的新实例并将其返回,你通常会期望有两个实例(每个服务一个)。这肯定会有问题:在Spring中,实例化的Bean默认有一个单子范围。这就是神奇之处。所有的@Configurationclasses都在启动时用CGLIB进行子类化。 

在子类中,子方法首先检查容器中是否有任何缓存(范围)的Bean,然后调用父方法并创建一个新的实例。请注意,从Spring 3.2开始,不再需要将CGLIB添加到你的classpath中,因为CGLIB类已经被重新打包到org.springframework.cglib下,并直接包含在spring-core JAR中。根据你的Bean的范围,其行为可能会有所不同。我们在这里讨论的是单体。

编写@Configuration类时的限制条件

  • 配置类必须以类的形式提供(即不是从工厂方法返回的实例),允许通过生成的子类进行运行时增强。
  • 配置类必须是非最终的。
  • 配置类必须是非本地的(即不能在一个方法中声明)。
  • 任何嵌套的配置类必须被声明为静态的。
  • @Bean方法不能反过来创建更多的配置类(任何这样的实例将被视为普通的Bean,其配置注解仍未被检测到)。

相关文章