版权声明:本文为 小异常 原创文章,非商用自由转载-保持署名-注明出处,谢谢!
本文网址:https://blog.csdn.net/sun8112133/article/details/104317579
在我之前写的博客中,只介绍了两种配置 Bean 的方式,其实它还有第三种方式,它可以减少配置文件,以编码的方式进行配置,也是目前主流的一种方式。早就想对它来个总结了,一直忙没顾上。
本篇博客主要来讲解配置 Bean 的第三种方式 —— 基于 Java 的配置。
一、@Configuration 与 @Bean 注解
@Configuration 是配置类注解,它用处非常大,是第三种配置的核心注解。而 @Bean 是 Bean 注解,一般在方法上标注,主要用于配置 Bean,经常与 @Configuration 注解结合使用。
1、小案例
@Configuration
public class MyConfig {
@Bean
public A aa() {
return new A();
}
@Bean
public B bb() {
return new B();
}
}
上面这段代码就相当于我们以前在 XML 文件中这样写,其中方法名相当于
id
属性:
<beans>
<bean id="aa" class="A的全类名" />
<bean id="bb" class="B的全类名" />
</beans>
在
main()
方法中,我们之前一直都是在加载 XML 文件,而现在我们需要加载的是配置类:
public class Main {
public static void main(String[] args) {
// 加载 MyConfig 这个配置类,注册配置类中的所有 Bean
ApplicationContext ioc = new AnnotationConfigApplicationContext(MyConfig.class);
A a = (A) ioc.getBean("aa");
B b = (B) ioc.getBean("bb");
}
}
2、注入 Bean 的依赖
在配置类中注入 Bean 的依赖时,也非常简单,只要有一个 Bean 方法调用另一个即可:
class A {
public A(B b) { }
}
class B { }
@Configuration
class MyConfig {
@Bean
public A aa() {
return new A(bb());
}
@Bean
public B bb() {
return new B();
}
}
二、@Import 注解
@Import 是一个导入注解,主要用在配置类中,允许从其他配置类中加载 @Bean,也就是加载配置的 Bean 实例。
@Configuration
class AConfig {
@Bean
public A aa() {
return new A();
}
}
@Configuration
@Import(AConfig.class)
class BConfig {
@Bean
public B bb() {
return new B();
}
}
class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(BConfig.class); // BConfig配置类 中 加载了 AConfig配置类,所以目前加载了两个配置类
B b = (B) ioc.getBean("bb");
A a = (A) ioc.getBean("aa");
}
}
三、配置生命周期
我们也可以在配置类中指定 Bean 的生命周期,也就是初始化和销毁方法。
class A {
public void init() {
System.out.println("我是 A 的 init 方法");
}
public void destroy() {
System.out.println("我是 A 的 destroy 方法");
}
}
@Configuration
class AConfig {
@Bean(initMethod = "init", destroyMethod = "destroy")
public A aa() {
return new A();
}
}
class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AConfig.class);
A a = (A) ioc.getBean("aa");
ioc.close();
}
}
四、配置作用域
Bean 的默认作用域是单实例的,可以通过 @Scope 注解改变其作用域,常见的两个作用域:
singleton
:默认值。容器初始化时创建 bean 实例。在整个容器的生命周期内只创建这一个 Bean。它是单例的。prototype
:原型的。容器初始化时不会创建 bean 实例。而在每次请求时都创建一个新的 Bean 实例,并返回。
@Configuration
class AConfig {
@Bean
@Scope("prototype")
public A aa() {
return new A();
}
}
class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext ioc = new AnnotationConfigApplicationContext(AConfig.class);
A a1 = (A) ioc.getBean("aa");
A a2 = (A) ioc.getBean("aa");
System.out.println(a1 == a2); // 输出:false
}
}