Spring @Configuration 注解
Spring @Configuration注解是 Spring 核心框架的一部分。Spring Configuration 注解表示该类具有@Bean定义方法。因此 Spring 容器可以处理该类并生成要在应用程序中使用的 Spring Bean。
Spring @Configuration
Spring @Configuration注释允许我们使用注释进行依赖注入。让我们了解如何创建 Spring 配置类。让我们创建一个简单的 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 配置类。
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 的新实例,并且它不会保持单例。为了证明这一点,让我们定义另一个将使用 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 不再是单例了,现在让我们再次MyConfiguration
使用@Configuration
注解进行注解并运行该类MySpringApp
。这次输出将如下所示。
MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856
因此,最好@Configuration
在配置类中使用注释,以确保我们的 spring 容器的行为符合我们的预期。如果出于某些奇怪的原因您不想使用@Configuration注释,我们仍然可以通过不调用方法而是使用通过@AutowiredmyBean()
注释配置的 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 存储库下载示例代码。