Spring @Configuration注解示例

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

在这篇文章中,我们将讨论一个非常重要的基于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的内容如下。

import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;

@Configuration
public class Application {

     @Bean
     public CustomerService customerService() {
         return new CustomerService();
     }
 
     @Bean
     public OrderService orderService() {
         return new OrderService();
     }
}

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

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

注入bean间的依赖关系

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

@Configuration
public class AppConfig {

    @Bean
    public Foo foo() {
        return new Foo(bar());
    }

    @Bean
    public Bar bar() {
        return new Bar();
    }
}

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

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

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

@Configuration
public class AppConfig {

    @Bean
    public ClientService clientService1() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientService clientService2() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientDao clientDao() {
        return new ClientDaoImpl();
    }
}

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,其配置注解仍未被检测到)。

相关文章

微信公众号

最新文章

更多