@Configuration注解使用详解【记录】

@Configuration注解

1、主要作用:

  • 标识配置类:@Configuration用于标识一个类是配置类,这是Spring Boot应用程序中的关键组件之一,用于定义和管理Bean的创建和配置(用于取代bean.xml配置文件注册bean对象)。通过使用@Configuration注解,我们告诉Spring容器这个类是一个配置类,并且应当被加载和处理。

  • 定义Bean:配置类通常包含一些用于创建和配置Bean的方法。这些方法使用@Bean注解来定义Bean,并且在Spring容器启动时被调用。通过@Configuration注解,我们可以将这些方法标识为Bean定义方法,使它们成为Spring应用程序上下文中的Bean。

  • 提供配置属性:配置类还可以使用@ConfigurationProperties注解提供应用程序的配置属性。@ConfigurationProperties注解允许我们将配置属性绑定到配置文件中的值,从而实现应用程序的配置管理。通过在配置类中使用@ConfigurationProperties注解,我们可以轻松地将配置属性注入到我们的应用程序中。

  • 条件化配置:配置类中的方法可以使用条件注解(如@ConditionalOnClass@ConditionalOnProperty等)来根据条件创建和注册Bean。这使得可以根据应用程序的环境条件来选择性地配置Bean。

  • 集中管理和组织配置信息:通过@Configuration注解可以将这些配置集中到一个或多个配置类中,方便开发和维护应用程序。

2、使用约束:

  • @Configuration注解作用在类、接口(包含注解)上;
  • @Configuration用于定义配置类,可替换XML配置文件,相当于XML形式的Spring配置;
  • @Configuration注解类中可以声明一个或多个 @Bean 注解的方法;
  • @Configuration注解作用的类不能是 final 类型;
  • @Configuration不可以是匿名类;
  • 嵌套的@Configuration类必须是 static 的。

3、使用示例1,标识配置类和定义bean:

@Configuration注解是Spring框架中的一个核心注解,用于标识一个类作为配置类,该类中可以定义Bean。当Spring容器启动时,它会扫描这些带有 @Configuration 注解的类,并将它们作为配置信息来处理。

这些配置类通常包含一个或多个带有 @Bean 注解的方法。@Bean 注解告诉Spring容器,方法返回的对象应该被注册为Spring应用上下文中的Bean,即被Spring管理的一个对象。

java 复制代码
@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

在这个例子中,AppConfig 类通过 @Configuration 注解标识为配置类,而 myBean 方法被 @Bean 注解标识,表明它将返回一个对象,该对象需要被注册到Spring的IoC容器中。当应用启动时,Spring容器会创建一个 MyBean 的实例,并将其作为Bean管理。

在例子中使用 @Configuration 注解的 AppConfig 类也会被Spring的IoC(控制反转)容器管理。当Spring应用上下文启动时,它会扫描并注册所有带有 @Configuration 注解的类作为配置类的Bean。这意味着,AppConfig 自身也是一个Bean,它会被注入到IoC容器中。

这允许在其他Bean中通过依赖注入的方式使用 AppConfig,尽管这在实际应用中不是很常见。通常,@Configuration 注解修饰的类被用来声明Bean和配置应用上下文,而不是作为被注入的服务。

综上所述,@Configuration 类在Spring中既充当配置信息的角色,又作为容器中的一个Bean存在,其作用是提供一个灵活且强大的方式来定义和组装Spring Bean,使得Spring的配置更加灵活和方便。

补充:@Configuration注解最常见的搭配使用有两个:@Bean@Scope

  • @Bean:等价于Spring中的bean标签用于注册bean对象的,给容器中添加组件,一般以方法名作为组件的id,配置类里面使用@Bean标注在方法上给容器注册组件,默认是单实例的。
java 复制代码
@Configuration(proxyBeanMethods = true) //告诉springboot这是一个配置类 == 配置文件
public class Myconfig {
    @Bean//给容器中添加组件,以方法名作为组件的id。
    // 返回类型为组件类型,返回的值,就是组件在容器中的实例
    public User user01(){
        User wangcai = new User("wangcai",23);
        //user组件依赖了pet组件
        wangcai.setPet(pet01());
        return wangcai;
    }
    @Bean
    public Pet pet01(){
        return new Pet("旺财");
    }
}
  • @Scope:用于声明该bean的作用域,作用域有singleton、prototype、request、session。
java 复制代码
@Configuration
public class MyConfig {
    @Bean("user")
    @Scope(SCOPE_PROTOTYPE)         //多例
    public User getUser(){
        System.out.println("User对象进行创建!");
        return new User("用户", 22, getDog());
    }
    @Bean("dog")
    @Scope(SCOPE_SINGLETON)         //单例
    public Dog getDog(){
        System.out.println("Dog对象进行创建!");
        return new Dog("金毛", 3);
    }
}

思考:那如何获取AppConfig中的MyBean?

在Spring框架中,获取 AppConfig 中定义的 MyBean 实例通常通过依赖注入(DI)来实现。这可以通过多种方式完成,包括构造函数注入、设置(setter)注入或字段注入。以下是一些示例:

  1. 构造函数注入
java 复制代码
@Component
public class SomeService {
    private MyBean myBean;

    @Autowired
    public SomeService(MyBean myBean) {
        this.myBean = myBean;
    }
    // 使用myBean
}
  1. 设置(Setter)注入
java 复制代码
@Component
public class SomeService {
    private MyBean myBean;

    @Autowired
    public void setMyBean(MyBean myBean) {
        this.myBean = myBean;
    }

    // 使用myBean
}
  1. 字段注入

在下面例子中,@Component 注解用于标记 SomeService 类,使其成为Spring管理的一个Bean。@Autowired 注解用于自动注入依赖,即告诉Spring框架应自动注入 MyBean 的实例。

java 复制代码
@Component
public class SomeService {
    @Autowired
    private MyBean myBean;

    // 使用myBean
}
  1. 通过 ApplicationContext 获取

还可以通过编程方式直接从 ApplicationContext 获取 MyBean 实例:

java 复制代码
public class SomeClass {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyBean myBean = context.getBean(MyBean.class);

        // 使用myBean
    }
}

最后一个示例演示了如何在非Spring管理的对象中获取 MyBean 实例。通过手动创建 ApplicationContext 并从中检索Bean,可以在任何地方获取 MyBean 的实例,但这种方法违背了依赖注入的原则,通常仅在特定场景下使用,如在应用的入口点或配置类中。

4、使用示例2,提供配置属性:

在Spring Boot应用程序中,@Configuration@ConfigurationProperties(prefix = "")是两个用于配置和管理应用程序设置的常用注解,它们扮演着不同但互补的角色。

  • @ConfigurationProperties注解:用于将配置文件中的属性绑定到一个POJO(Plain Old Java Object)上。通过指定prefix属性,可以将配置文件中特定前缀的属性绑定到同名的POJO属性上。这种方式简化了配置管理,使得配置数据的组织和使用变得更加方便。

注意:当你在类上使用 @ConfigurationProperties 注解时,你通常希望SpringBoot能够自动绑定配置文件中的属性到该类的字段上。然而,仅仅使用 @ConfigurationProperties 注解并不足以让SpringBoot自动配置这些属性;你还需要指示SpringBoot去寻找这些配置类并将其注册为Spring容器中的bean,通常在配置类上使用@EnableConfigurationProperties注解或直接在@ConfigurationProperties类上声明一个Spring组件注解(如 @Component@Configuration等)。

用法一:

通过@Component@ConfigurationProperties(prefix = "")注解组合声明配置类

yaml 复制代码
redis:
	database: 1
	host: redis-xxxxxxxxxx-proxy-nlb.xxxxx-xxxx-xx.xxxxx.com
	port: 6379
	password: xxxxxx
	timeout: 2000

在RedisConfiguration类中,将yaml配置中的属性注入到RedisConfiguration配置类中。

java 复制代码
@Component
@ConfigurationProperties(prefix = "redis")
public class RedisConfiguration {
    private String database;
    private String host;
	private Integer port;
	private String password;
	// 其它属性...
    // getters 和 setters
}

在DemoImpl类中,直接可以注入RedisConfiguration通过获取属性的方式获取配置文件中的配置。

java 复制代码
@Service
public class DemoImpl implements Demo() {
	@Autowired
	private RedisConfiguration redisConfiguration;

	@Override()
	public void demo() {
		String host = redisConfiguration.getHost();
		System.out.println(host);
	}
}

用法二:

使用@EnableConfigurationProperties注解激活和注册对应的配置类到IOC容器中。

yaml 复制代码
aces:
	token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	path: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

首先将aces配置文件中的属性注入到AcesConfigurationProperties类中,这里无需通过@Component注解将AcesConfigurationProperties 注入IOC容器。

java 复制代码
@Data
@ConfigurationProperties(prefix = "aces")
public class AcesConfigurationProperties {
    private String token;
	private String path;
}

在AcesConfiguration配置类中使用@EnableConfigurationProperties({AcesConfigurationProperties.class})注解来激活和注册 AcesConfigurationProperties类作为Spring管理的Bean。这一步确保了Spring容器会自动绑定配置文件中的属性到 AcesConfigurationProperties类的字段上。

java 复制代码
@Configuration
@EnableConfigurationProperties({AcesConfigurationProperties.class})
public class AcesConfiguration {
    @Autowired
    private AcesConfigurationProperties acesConfigurationProperties;

	@Bean("tdeClient")
    public TdeClient tdeClient(){
        TdeClient tdeClientBean = new TdeClient();
        TdeClient.setToken(acesConfigurationProperties.getToken());
        TdeClient.setPath(acesConfigurationProperties.getPath());
        return tdeClient;
    }
}
java 复制代码
@Service
public class DemoImpl implements Demo() {
	@Autowired
	private TdeClient tdeClient;

	@Override()
	public void demo() {
		String token= tdeClient.token();
		System.out.println(token);
	}
}

结合使用@Configuration@ConfigurationProperties可以提供一种强大的机制来管理应用程序配置,使得配置数据既易于组织,也便于访问和使用。

@Configuration注解在Spring和Spring boot中有什么区别?

在Spring和SpringBoot中,@Configuration 注解的核心功能是相同的:都用来标识配置类,并允许你在这些类中定义Bean。但是,SpringBoot对这个注解提供了一些额外的处理,使得它在SpringBoot应用中的行为与传统的Spring应用略有不同。

1、Spring中的@Configuration

在Spring框架中,@Configuration注解指示一个类包含一个或多个@Bean定义,这些定义将由Spring容器管理。你需要使用@ComponentScan来指定应当扫描哪些包来发现Bean,并使用@Import来引入其他配置类,或者使用<import>标签在XML配置中做到这一点。

2、Spring Boot中的@Configuration

SpringBoot继承了Spring的这些特性,并添加了自动配置的概念。SpringBoot的@SpringBootApplication注解是一个组合注解,它包括了@Configuration@EnableAutoConfiguration@ComponentScan。因此,在SpringBoot应用中,你通常不需要显式地标记@Configuration,除非你要创建额外的配置类。

@EnableAutoConfiguration告诉SpringBoot根据类路径下的jar包依赖、定义的Bean和各种属性设置自动配置应用。这意味着SpringBoot会尝试智能地猜测你需要哪些功能,并自动配置它们。这大大简化了配置过程,因为许多库和功能的默认设置会在没有任何明确配置的情况下自动设置。

3、总结:

  • @Configuration 在Spring和SpringBoot中的基本作用是一样的:它用于定义配置类;
  • SpringBoot提供了额外的自动配置特性,允许更快速地设置和启动项目;
  • 在SpringBoot中,通常不需要显式的@Configuration声明,除非你要定义额外的配置类;
  • SpringBoot中的@SpringBootApplication组合注解已经包含了@Configuration,以及其他用于自动配置的注解。

因此,在使用SpringBoot时,通常会体验到更加"约定大于配置"的开发流程。

相关推荐
魔道不误砍柴功2 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2342 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨2 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
种树人202408192 小时前
如何在 Spring Boot 中启用定时任务
spring boot
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity4 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^5 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋35 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx