Spring @Configuration 注解

春季 @Configuration 注釋是 Spring 核心框架的一部分。Spring Configuration 注釋表示該類具有 @Bean 定義方法。因此,Spring 容器可以處理該類並生成 Spring Beans 供應用程序使用。

Spring @Configuration

Spring @Configuration 注釋允許我們使用注釋進行 依賴注入。讓我們了解如何創建 Spring Configuration 類。讓我們創建一個簡單的 Java Bean 類。

package com.journaldev.spring;

public class MyBean {

	public MyBean() {
		System.out.println("MyBean instance created");
	}
	
}

在使用任何 Spring 框架類之前,我們必須將其相關依賴添加到 Maven 項目中。

<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.0.6.RELEASE</version>
</dependency>

現在讓我們創建 Spring Configuration 類。

package com.journaldev.spring;

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

@Configuration
public class MyConfiguration {

    @Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
}

讓我們編寫一個簡單的類並配置我們的簡單 Spring 配置類。

package com.journaldev.spring;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MySpringApp {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
		ctx.register(MyConfiguration.class);
		ctx.refresh();

		// MyBean mb1 = ctx.getBean(MyBean.class);

		// MyBean mb2 = ctx.getBean(MyBean.class);

		ctx.close();
	}

}

如果運行上述應用程序,它將生成以下輸出:

May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy
MyBean instance created
May 23, 2018 12:34:54 PM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@ff5b51f: startup date [Wed May 23 12:34:54 IST 2018]; root of context hierarchy

請注意,Spring 在我們甚至還沒有請求它之前就將bean加載到其上下文中。這是為了確保所有的bean都被正確配置,並且如果出現問題,應用程序將快速失敗。此外,必須調用ctx.refresh(),否則當我們嘗試從上下文中獲取任何bean時,將會出現以下錯誤。

Exception in thread "main" java.lang.IllegalStateException: org.springframework.context.annotation.AnnotationConfigApplicationContext@f0f2775 has not been refreshed yet
	at org.springframework.context.support.AbstractApplicationContext.assertBeanFactoryActive(AbstractApplicationContext.java:1076)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1106)
	at com.journaldev.spring.MySpringApp.main(MySpringApp.java:11)

如果取消註釋我獲取MyBean實例的語句,您將注意到它並不調用MyBean的構造函數。這是因為spring beans的默認作用域是Singleton。我們可以使用@Scope註釋來更改它。

如果我們移除@Configuration註釋會怎樣?

如果我們從MyConfiguration類中刪除@Configuration註釋,會發生什麼情況。您將注意到它仍然如預期地工作,並且spring beans被註冊並檢索為單例類。但在這種情況下,如果我們調用myBean()方法,那麼它將是一個普通的java方法調用,我們將獲得MyBean的新實例,它將不再是單例的。為了證明這一點,讓我們定義另一個將使用MyBean實例的bean。

package com.journaldev.spring;

public class MyBeanConsumer {

	public MyBeanConsumer(MyBean myBean) {
		System.out.println("MyBeanConsumer created");
		System.out.println("myBean hashcode = "+myBean.hashCode());
	}

}

我們更新的Spring配置類如下:

package com.journaldev.spring;

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

//@Configuration
public class MyConfiguration {

	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

現在當我們運行MySpringApp類時,它生成以下輸出。

MyBean instance created
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1647766367

因此,MyBean不再是單例,現在讓我們再次用@Configuration注解註釋MyConfiguration,並運行MySpringApp類。這次的輸出將如下。

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

因此,最好使用@Configuration注解與配置類,以確保我們的Spring容器的行為與我們期望的一樣。如果出於一些奇怪的原因你不想使用@Configuration注解,我們仍然可以通過不調用myBean()方法,而是使用通過@Autowired注解配置的MyBean的實例變量來創建我們的配置類。像下面的代碼一樣也可以正常工作。

package com.journaldev.spring;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration
public class MyConfiguration {

	@Autowired
	MyBean myBean;
	
	@Bean
    public MyBean myBean() {
		return new MyBean();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean);
	}
}

這就是有關Spring配置注解的全部,我們將在未來的帖子中深入研究其他Spring注解。

您可以從我們的GitHub存儲庫下載示例代碼。

Source:
https://www.digitalocean.com/community/tutorials/spring-configuration-annotation