Spring 学习笔记 之 基于注解的配置

Spring 基于注解的配置

基于注解的配置

从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。

在 XML 注入之前进行注解注入,因此后者的配置将通过两种方式的属性连线被前者重写。

注解连线在默认情况下在 Spring 容器中不打开。因此,在可以使用基于注解的连线之前,我们将需要在我们的 Spring 配置文件中启用它。所以如果你想在 Spring 应用程序中使用的任何注解,可以考虑到下面的配置文件。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

一旦 被配置后,你就可以开始注解你的代码,表明 Spring 应该自动连接值到属性,方法和构造函数。让我们来看看几个重要的注解,并且了解它们是如何工作的:

序号 注解 & 描述
1

@Required 注解应用于 bean 属性的 setter 方法。

2 @Autowired 注解可以应用到 bean 属性的 setter 方法,非 setter 方法,构造函数和属性。
3

@Qualifier通过指定确切的将被连线的 bean,@Autowired 和 @Qualifier 注解可以用来删除混乱。

4

JSR-250 Annotations

Spring 支持 JSR-250 的基础的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。

 Spring @Required 注释

@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。下面显示的是一个使用 @Required 注释的示例。

示例:

步骤 描述
1 创建一个名为 SpringExample 的项目,并且在所创建项目的 src 文件夹下创建一个名为 com.tutorialspoint 的包。
2 使用 Add External JARs 选项添加所需的 Spring 库文件,就如在 Spring Hello World Example 章节中解释的那样。
3 在 com.tutorialspoint 包下创建 Java 类 Student 和 MainApp
4 在 src 文件夹下创建 Beans 配置文件 Beans.xml
5 最后一步是创建所有 Java 文件和 Bean 配置文件的内容,并且按如下解释的那样运行应用程序。

下面是 Student.java 文件的内容:

package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Required;
public class Student {
   private Integer age;
   private String name;
   @Required
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }
   @Required
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
}

 下面是 MainApp.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      Student student = (Student) context.getBean("student");
      System.out.println("Name : " + student.getName() );
      System.out.println("Age : " + student.getAge() );
   }
}

下面是配置文件 Beans.xml: 文件的内容:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />

      <!-- try without passing age and check the result -->
      <!-- property name="age"  value="11"-->
   </bean>

</beans>

一旦你已经完成的创建了源文件和 bean 配置文件,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将引起 BeanInitializationException 异常,并且会输出一下错误信息和其他日志消息:

Property 'age' is required for bean 'student'

下一步,在你按照如下所示从 “age” 属性中删除了注释,你可以尝试运行上面的示例:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>

</beans>

现在上面的示例将产生如下结果:

Name : Zara
Age : 11

Spring @Autowired 注释

使用 Spring 开发时,进行配置主要有两种方式,一是 xml 的方式,二是 java config 的方式。Spring 技术自身也在不断的发展和改变,从当前 Springboot 的火热程度来看,java config 的应用是越来越广泛了,在使用 java config 的过程当中,我们不可避免的会有各种各样的注释打交道,其中,我们使用最多的注释应该就是 @Autowired 注释了。这个注释的功能就是为我们注入一个定义好的 bean。

@Autowired 注释的作用到底是什么?

@Autowired 这个注释我们经常在使用,现在,我想问的是,它的作用到底是什么呢?

首先,我们从所属范围来看,事实上这个注释是属于 Spring 的容器配置的一个注释,与它同属容器配置的注释还有:@Required,@Primary, @Qualifier 等等。因此 @Autowired 注释是一个用于容器 ( container ) 配置的注释。

其次,我们可以直接从字面意思来看,@autowired 注释来源于英文单词 autowire,这个单词的意思是自动装配的意思。自动装配又是什么意思?这个词语本来的意思是指的一些工业上的用机器代替人口,自动将一些需要完成的组装任务,或者别的一些任务完成。而在 Spring 的世界当中,自动装配指的就是使用将 Spring 容器中的 bean 自动的和我们需要这个 bean 的类组装在一起。

@Autowired 注释用法

在分析这个注释的实现原理之前,我们不妨先来回顾一下 @Autowired 注释的用法。

将 @Autowired 注释应用于构造函数,如以下示例所示

public class MovieRecommender {
 
    private final CustomerPreferenceDao customerPreferenceDao;
 
    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }
 
    // ...
}

将 @Autowired 注释应用于 setter 方法

public class SimpleMovieLister {
 
    private MovieFinder movieFinder;
 
    @Autowired
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
 
    // ...
}

将 @Autowired 注释应用于具有任意名称和多个参数的方法

public class MovieRecommender {
 
    private MovieCatalog movieCatalog;
 
    private CustomerPreferenceDao customerPreferenceDao;
 
    @Autowired
    public void prepare(MovieCatalog movieCatalog,
            CustomerPreferenceDao customerPreferenceDao) {
        this.movieCatalog = movieCatalog;
        this.customerPreferenceDao = customerPreferenceDao;
    }
 
    // ...
}

您也可以将 @Autowired 注释应用于字段,或者将其与构造函数混合,如以下示例所示

public class MovieRecommender {
 
    private final CustomerPreferenceDao customerPreferenceDao;
 
    @Autowired
    private MovieCatalog movieCatalog;
 
    @Autowired
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }
 
    // ...
}

直接应用于字段是我们使用的最多的一种方式,但是使用构造方法注入从代码层面却是更加好的。除此之外,还有以下不太常见的几种方式

将 @Autowired 注释添加到需要该类型数组的字段或方法,则 Spring 会从 ApplicationContext 中搜寻符合指定类型的所有 bean,如以下示例所示:

public class MovieRecommender {
 
    @Autowired
    private MovieCatalog[] movieCatalogs;
 
    // ...
}

数组可以,我们可以马上举一反三,那容器也可以吗,答案是肯定的,下面是 set 以及 map 的例子:

public class MovieRecommender {
 
    private Set<MovieCatalog> movieCatalogs;
 
    @Autowired
    public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }
 
    // ...
}
public class MovieRecommender {
 
    private Map<String, MovieCatalog> movieCatalogs;
 
    @Autowired
    public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
        this.movieCatalogs = movieCatalogs;
    }
 
    // ...
}

以上就是 @Autowired 注释的主要使用方式,经常使用 Spring 的话应该对其中常用的几种不会感到陌生。

Spring @Qualifier 注释

可能会有这样一种情况,当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱。下面显示的是使用 @Qualifier 注释的一个示例。

示例

步骤 描述
1 创建一个名为 SpringExample 的项目,并且在所创建项目的 src 文件夹下创建一个名为 com.tutorialspoint 的包。
2 使用 Add External JARs 选项添加所需的 Spring 库文件,就如在 Spring Hello World Example 章节中解释的那样。
3 在 com.tutorialspoint 包下创建 Java 类 StudentProfile 和 MainApp
4 在 src 文件夹下创建 Beans 配置文件 Beans.xml
5 最后一步是创建所有 Java 文件和 Bean 配置文件的内容,并且按如下解释的那样运行应用程序。

这里是 Student.java 文件的内容:

package com.tutorialspoint;
public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }   
   public Integer getAge() {
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }  
   public String getName() {
      return name;
   }
}

这里是 Profile.java 文件的内容:

package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Profile {
   @Autowired
   @Qualifier("student1")
   private Student student;
   public Profile(){
      System.out.println("Inside Profile constructor." );
   }
   public void printAge() {
      System.out.println("Age : " + student.getAge() );
   }
   public void printName() {
      System.out.println("Name : " + student.getName() );
   }
}

下面是 MainApp.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      Profile profile = (Profile) context.getBean("profile");
      profile.printAge();
      profile.printName();
   }
}

考虑下面配置文件 Beans.xml 的示例:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for profile bean -->
   <bean id="profile" class="com.tutorialspoint.Profile">
   </bean>

   <!-- Definition for student1 bean -->
   <bean id="student1" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>

   <!-- Definition for student2 bean -->
   <bean id="student2" class="com.tutorialspoint.Student">
      <property name="name"  value="Nuha" />
      <property name="age"  value="2"/>
   </bean>

</beans>

一旦你在源文件和 bean 配置文件中完成了上面两处改变,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将会输出以下消息:

Inside Profile constructor.
Age : 11
Name : Zara

Spring JSR-250 注释

Spring还使用基于 JSR-250 注释,它包括 @PostConstruct, @PreDestroy 和 @Resource 注释。因为你已经有了其他的选择,尽管这些注释并不是真正所需要的,但是关于它们仍然让我给出一个简短的介绍。

@PostConstruct 和 @PreDestroy 注释:

为了定义一个 bean 的安装和卸载,我们使用 init-method 和/或 destroy-method 参数简单的声明一下 。init-method 属性指定了一个方法,该方法在 bean 的实例化阶段会立即被调用。同样地,destroy-method 指定了一个方法,该方法只在一个 bean 从容器中删除之前被调用。

你可以使用 @PostConstruct 注释作为初始化回调函数的一个替代,@PreDestroy 注释作为销毁回调函数的一个替代,其解释如下示例所示。

示例

步骤 描述
1 创建一个名为 SpringExample 的项目,并且在所创建项目的 src 文件夹下创建一个名为 com.tutorialspoint 的包。
2 使用 Add External JARs 选项添加所需的 Spring 库文件,就如在 Spring Hello World Example 章节中解释的那样。
3 在 com.tutorialspoint 包下创建 Java 类 HelloWorld 和 MainApp
4 在 src 文件夹下创建 Beans 配置文件 Beans.xml
5 最后一步是创建所有 Java 文件和 Bean 配置文件的内容,并且按如下解释的那样运行应用程序。

这里是 HelloWorld.java 文件的内容:

package com.tutorialspoint;
import javax.annotation.*;
public class HelloWorld {
   private String message;
   public void setMessage(String message){
      this.message  = message;
   }
   public String getMessage(){
      System.out.println("Your Message : " + message);
      return message;
   }
   @PostConstruct
   public void init(){
      System.out.println("Bean is going through init.");
   }
   @PreDestroy
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}

下面是 MainApp.java 文件的内容。这里你需要注册一个关闭钩 registerShutdownHook() 方法,该方法在 AbstractApplicationContext 类中被声明。这将确保一个完美的关闭并调用相关的销毁方法。

package com.tutorialspoint;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      AbstractApplicationContext context = 
                          new ClassPathXmlApplicationContext("Beans.xml");
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}

下面是配置文件 Beans.xml,该文件在初始化和销毁方法中需要使用。

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <bean id="helloWorld" 
       class="com.tutorialspoint.HelloWorld"
       init-method="init" destroy-method="destroy">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

一旦你在源文件和 bean 配置文件中完成了上面两处改变,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将会输出以下消息:

Bean is going through init.
Your Message : Hello World!
Bean will destroy now.

@Resource 注释:

你可以在字段中或者 setter 方法中使用 @Resource 注释,它和在 Java EE 5 中的运作是一样的。@Resource 注释使用一个 ‘name’ 属性,该属性以一个 bean 名称的形式被注入。你可以说,它遵循 by-name 自动连接语义,如下面的示例所示:

package com.tutorialspoint;
import javax.annotation.Resource;
public class TextEditor {
   private SpellChecker spellChecker;
   @Resource(name= "spellChecker")
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker(){
      return spellChecker;
   }
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

如果没有明确地指定一个 ‘name’,默认名称源于字段名或者 setter 方法。在字段的情况下,它使用的是字段名;在一个 setter 方法情况下,它使用的是 bean 属性名称。

Spring 基于 Java 的配置

到目前为止,你已经看到如何使用 XML 配置文件来配置 Spring bean。如果你熟悉使用 XML 配置,那么我会说,不需要再学习如何进行基于 Java 的配置是,因为你要达到相同的结果,可以使用其他可用的配置。

基于 Java 的配置选项,可以使你在不用配置 XML 的情况下编写大多数的 Spring,但是一些有帮助的基于 Java 的注解,解释如下:

@Configuration 和 @Bean 注解

带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。最简单可行的 @Configuration 类如下所示:

package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

上面的代码将等同于下面的 XML 配置:

<beans>
   <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" />
</beans>

在这里,带有 @Bean 注解的方法名称作为 bean 的 ID,它创建并返回实际的 bean。你的配置类可以声明多个 @Bean。一旦定义了配置类,你就可以使用 AnnotationConfigApplicationContext 来加载并把他们提供给 Spring 容器,如下所示:

public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(HelloWorldConfig.class); 
   HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
   helloWorld.setMessage("Hello World!");
   helloWorld.getMessage();
}

你可以加载各种配置类,如下所示:

public static void main(String[] args) {
   AnnotationConfigApplicationContext ctx = 
   new AnnotationConfigApplicationContext();
   ctx.register(AppConfig.class, OtherConfig.class);
   ctx.register(AdditionalConfig.class);
   ctx.refresh();
   MyService myService = ctx.getBean(MyService.class);
   myService.doStuff();
}

例子

步骤 描述
1 创建一个名称为 SpringExample 的项目,并且在创建项目的 src 文件夹中创建一个包 com.tutorialspoint
2 使用 Add External JARs 选项,添加所需的 Spring 库,解释见 Spring Hello World Example 章节。
3 因为你是使用基于 java 的注解,所以你还需要添加来自 Java 安装目录的 CGLIB.jar 和可以从 asm.ow2.org 中下载的 ASM.jar 库。
4 在 com.tutorialspoint 包中创建 Java 类 HelloWorldConfigHelloWorld 和 MainApp
5 最后一步是创建的所有 Java 文件和 Bean 配置文件的内容,并运行应用程序,解释如下所示。

这里是 HelloWorldConfig.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class HelloWorldConfig {
   @Bean 
   public HelloWorld helloWorld(){
      return new HelloWorld();
   }
}

这里是 HelloWorld.java 文件的内容:

package com.tutorialspoint;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public void getMessage(){
      System.out.println("Your Message : " + message);
   }
}

下面是 MainApp.java 文件的内容:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext ctx = 
      new AnnotationConfigApplicationContext(HelloWorldConfig.class);

      HelloWorld helloWorld = ctx.getBean(HelloWorld.class);

      helloWorld.setMessage("Hello World!");
      helloWorld.getMessage();
   }
}

结果:

Your Message : Hello World!

注入 Bean 的依赖性

当 @Beans 依赖对方时,表达这种依赖性非常简单,只要有一个 bean 方法调用另一个,如下所示:

package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
   @Bean
   public Foo foo() {
      return new Foo(bar());
   }
   @Bean
   public Bar bar() {
      return new Bar();
   }
}

这里,foo Bean 通过构造函数注入来接收参考基准。现在,让我们看到一个正在执行的例子:

例子:

步骤 描述
1 创建一个名称为 SpringExample 的项目,并且在创建项目的 src 文件夹中创建一个包 com.tutorialspoint
2 使用 Add External JARs 选项,添加所需的 Spring 库,解释见 Spring Hello World Example 章节。
3 因为你是使用基于 java 的注解,所以你还需要添加来自 Java 安装目录的 CGLIB.jar 和可以从 asm.ow2.org 中下载的 ASM.jar 库。
4 在 com.tutorialspoint 包中创建 Java 类 TextEditorConfigTextEditorSpellChecker 和 MainApp
5 最后一步是创建的所有 Java 文件和 Bean 配置文件的内容,并运行应用程序,解释如下所示。

这里是 TextEditorConfig.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class TextEditorConfig {
   @Bean 
   public TextEditor textEditor(){
      return new TextEditor( spellChecker() );
   }
   @Bean 
   public SpellChecker spellChecker(){
      return new SpellChecker( );
   }
}

下面是另一个依赖的类文件 SpellChecker.java 的内容:

package com.tutorialspoint;
public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }

}

下面是 MainApp.java 文件的内容:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext ctx = 
      new AnnotationConfigApplicationContext(TextEditorConfig.class);

      TextEditor te = ctx.getBean(TextEditor.class);

      te.spellCheck();
   }
}

一旦你完成了创建所有的源文件并添加所需的额外的库后,我们就可以运行该应用程序。你应该注意这里不需要配置文件。如果你的应用程序一切都正常,将输出以下信息:

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

 

@Import 注解:

@import 注解允许从另一个配置类中加载 @Bean 定义。考虑 ConfigA 类,如下所示:

@Configuration
public class ConfigA {
   @Bean
   public A a() {
      return new A(); 
   }
}

你可以在另一个 Bean 声明中导入上述 Bean 声明,如下所示:

@Configuration
@Import(ConfigA.class)
public class ConfigB {
   @Bean
   public B b() {
      return new B(); 
   }
}

现在,当实例化上下文时,不需要同时指定 ConfigA.class 和 ConfigB.class,只有 ConfigB 类需要提供,如下所示:

public static void main(String[] args) {
   ApplicationContext ctx = 
   new AnnotationConfigApplicationContext(ConfigB.class);
   // now both beans A and B will be available...
   A a = ctx.getBean(A.class);
   B b = ctx.getBean(B.class);
}

生命周期回调

@Bean 注解支持指定任意的初始化和销毁的回调方法,就像在 bean 元素中 Spring 的 XML 的初始化方法和销毁方法的属性:

public class Foo {
   public void init() {
      // initialization logic
   }
   public void cleanup() {
      // destruction logic
   }
}

@Configuration
public class AppConfig {
   @Bean(initMethod = "init", destroyMethod = "cleanup" )
   public Foo foo() {
      return new Foo();
   }
}

指定 Bean 的范围:

默认范围是单实例,但是你可以重写带有 @Scope 注解的该方法,如下所示:

@Configuration
public class AppConfig {
   @Bean
   @Scope("prototype")
   public Foo foo() {
      return new Foo();
   }
}

 

 

 

おすすめ

転載: blog.csdn.net/youandme520/article/details/112228528