Spring `@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 bean的默认作用域是 Singleton。我们可以使用 @Scope
注解来改变它。
如果我们移除 @Configuration 注解会发生什么?
如果我们从 MyConfiguration 类中移除 @Configuration 注解会发生什么呢?你会注意到它仍然按预期工作,并且 spring bean 被注册并检索为单例类。但在这种情况下,如果我们调用 myBean()
方法,那么它将成为一个普通的 Java 方法调用,我们将获得一个新的 MyBean 实例,并且它将不再是单例的。为了证明这一点,让我们定义另一个 bean,它将使用 MyBean 实例。
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