Spring @Configuration批注

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

Spring @Configuration注释是Spring核心框架的一部分。 Spring Configuration批注指示该类具有@Bean定义方法。 因此,Spring容器可以处理该类并生成要在应用程序中使用的Spring Bean。

Spring @Configuration (Spring @Configuration)

Spring @Configuration annotation allows us to use annotations for dependency injection. Let’s understand how to create Spring Configuration classes.

Spring @Configuration批注允许我们使用批注进行依赖项注入 。 让我们了解如何创建Spring Configuration类。

Let’s create a simple java bean class.

让我们创建一个简单的Java bean类。

package com.journaldev.spring;

public class MyBean {

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

Before we use any of the Spring framework classes, we will have to add it’s dependencies to the maven project.

在使用任何Spring框架类之前,我们必须将其依赖项添加到maven项目中。

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

Now let’s create the Spring Configuration class.

现在让我们创建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();
	}
	
}

Let’s write a simple class and configure our simple Spring configuration class.

让我们编写一个简单的类并配置我们的简单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();
	}

}

If you run above application, it will produce output like this:

如果您在上面的应用程序上运行,它将产生如下输出:

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 hierarchyMyBean 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

Notice that Spring loads beans into it’s context before we have even requested it. This is to make sure all the beans are properly configured and application fail-fast if something goes wrong.

注意,Spring甚至在我们请求之前就将bean加载到其上下文中。 这是为了确保所有Bean都已正确配置,并且如果出现问题,应用程序也会快速失败。

Also ctx.refresh() must be called, otherwise we will get following error when we will try to get any bean from the context.

另外,必须调用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)

If you uncomment the statements where I am getting MyBean instances, you will notice that it’s not calling the constructor of MyBean. It’s because the default scope of spring beans is Singleton. We can change it using @Scope annotation.

如果取消注释我在哪里获取MyBean实例的语句,您会注意到它没有在调用MyBean的构造函数。 这是因为spring bean的默认范围是Singleton。 我们可以使用@Scope批注进行更改。

如果我们删除@Configuration注释怎么办? (What if we remove @Configuration annotation?)

What will happen if we remove the @Configuration annotation from MyConfiguration class. You will notice that it still works as expected and spring beans are registered and retrieved as singleton classes. But in this case, if we make a call to myBean() method then it will be a plain java method call and we will get a new instance of MyBean and it won’t remain singleton. To prove this point, let’s define another bean that will be using MyBean instance.

如果我们从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());
	}

}

Our updated Spring Configuration class is:

我们更新的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();
	}
	
	@Bean
    public MyBeanConsumer myBeanConsumer() {
		return new MyBeanConsumer(myBean());
	}
}

Now when we run the MySpringApp class, it generates following output.

现在,当我们运行MySpringApp类时,它将生成以下输出。

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

So MyBean is not singleton anymore, now let’s annotate MyConfiguration with @Configuration annotation again and run the MySpringApp class. This time output will be like below.

因此,MyBean不再是单例,现在让我们再次使用@Configuration注释对MyConfiguration进行注释,并运行MySpringApp类。 此时间输出将如下所示。

MyBean instance created
MyBeanConsumer created
myBean hashcode = 1095088856

So it’s better to use @Configuration annotation with configuration classes to make sure our spring container is behaving like the way we want it to.

因此,最好将@Configuration批注与配置类一起使用,以确保我们的spring容器表现出我们想要的方式。

If you don’t want to use @Configuration annotation for some weird reasons, we can still create our configuration class by not calling the myBean() method and rather using an instance variable of MyBean configured through @Autowired annotation. Something like below code will work as well.

如果出于某些奇怪的原因不想使用@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);
	}
}

That’s all for Spring Configuration annotation, we will look into other spring annotations in future posts.

这就是Spring Configuration注释的全部内容,我们将在以后的文章中探讨其他spring注释。

GitHub Repository. GitHub Repository下载示例代码。

翻译自: https://www.journaldev.com/21033/spring-configuration-annotation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值