Spring注解-(三)@Configuration的用法

本文最后更新于:June 14, 2022 pm

Spring 是目前主流的 Java Web 开发框架,是 Java 世界最为成功的框架。Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。该框架是一个轻量级的开源框架,具有很高的凝聚力和吸引力。Spring 框架不局限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何 Java 应用都可以从 Spring 中受益。Spring 框架还是一个超级粘合平台,除了自己提供功能外,还提供粘合其他技术和框架的能力。

目录

@Configuration和不加@Configuration有什么区别?

  • 不加
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.OrderS;
import com.SpringTestAnnotation.TestValue.OurAnno;
import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan("com.SpringTestAnnotation")
public class TestConfig {

@Bean
public OrderS orderS(){
return new OrderS();
}

@Bean
public Per per(){
orderS(); //报错Method annotated with @Bean is called directly. Use dependency injection instead
return new Per();
}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.OrderS;
import com.SpringTestAnnotation.TestValue.OurAnno;
import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan("com.SpringTestAnnotation")
@Configuration
public class TestConfig {

@Bean
public OrderS orderS(){
return new OrderS();
}

@Bean
public Per per(){
orderS();
return new Per();
}

}

在使用了@Configuration注解后,再跑一下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
public class TestAnnotation {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestConfig.class);
System.out.println(applicationContext.getBean("orderS"));
System.out.println(applicationContext.getBean("orderS"));
System.out.println(applicationContext.getBean("orderS"));
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.SpringTestAnnotation;

import com.SpringTestAnnotation.TestValue.OrderS;
import com.SpringTestAnnotation.TestValue.OurAnno;
import com.SpringTestAnnotation.TestValue.Per;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;

/**
* @Author DragonOne
* @Date 2022/6/10 11:16
* @墨水记忆 www.tothefor.com
*/
@ComponentScan("com.SpringTestAnnotation")
@Configuration
public class TestConfig {

@Bean
public OrderS orderS(){
return new OrderS();
}

@Bean
public Per per(){
System.out.println(orderS());
System.out.println(orderS());
return new Per();
}

}

最后输出结果:

1
2
3
4
5
com.SpringTestAnnotation.TestValue.OrderS@6b53e23f
com.SpringTestAnnotation.TestValue.OrderS@6b53e23f
com.SpringTestAnnotation.TestValue.OrderS@6b53e23f
com.SpringTestAnnotation.TestValue.OrderS@6b53e23f
com.SpringTestAnnotation.TestValue.OrderS@6b53e23f

可以看见,所以的Bean都是同一个。

说明

在看视频学习的时候,视频中的老师没有加@Configuration也是可以跑的,但是自己尝试的时候不行,会报错。但是,视频中老师的最后输出结果和上面的是不一样的。

  • 没有加@Configuration注解,那么最后打印的结果中前两个是不一样的,后三个是一样的。

  • 加了@Configuration注解后,所以的输出结果均相同。

  • 原因:在没有加@Configuration注解的情况下,前两个就和正常的Java对象创建一样,每一次都会new一个新的;而在加了@Configuration注解的情况下,在Spring的作用下,会先去找有没有需要的,如果有则直接用,没有则才创建。具体的实现只要通过代理实现(加了@Configuration注解后,对应的类对象TestConfig将会被代理,然后代理对象再去执行orderS()方法。而代理对象执行的时候,并不是直接执行new进行创建,而是会先进行判断当前的OrderS()方法对应的Bean是否已经创建了,如果没有则才会执行创建并放到Spring容器中去;如果Spring容器中已经存在的,则不会执行方法中的new进行创建,而是直接拿取容器中的)。