从 Spring 2.5 开始就可以使用注解来配置依赖注入。而不是采用 XML 来描述一个 bean 连线,你可以使用相关类,方法或字段声明的注解,将 bean 配置移动到组件类本身。
<context:annotation-config/>
@Required | bean类的 setter 方法(bean必须写这个属性) |
@Autowired | 注解可以应用到 bean 属性的 setter 方法(bytype),非 setter 方法,构造函数(自动调用构造函数并匹配参数)和属性(可以省略setter方法)。 |
@Qualifier | 通过指定确切的将被连线的 bean,@Autowired 和 @Qualifier 注解可以用来删除混乱。 |
JSR-250 | Spring 支持 JSR-250 的基础的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。 |
Spring @Required 注释
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。下面显示的是一个使用 @Required 注释的示例。
@Required
public void setAge(Integer age) { this.age = age; }
@Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
Spring @Autowired 注释
@Autowired 注释对在哪里和如何完成自动连接提供了更多的细微的控制。
@Autowired 注释可以在 setter 方法中被用于自动连接 bean
当 Spring遇到一个在 setter 方法中使用的 @Autowired 注释,它会在方法中视图执行 byType 自动连接。
@Autowired
public void setSpellChecker( SpellChecker spellChecker ){ this.spellChecker = spellChecker; }
属性中的 @Autowired
你可以在属性中使用 @Autowired 注释来除去 setter 方法。当使用 为自动连接属性传递的时候,Spring 会将这些传递过来的值或者引用自动分配给那些属性。所以利用在属性中 @Autowired 的用法,你的TextEditor.java 文件将变成如下所示:
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
@Autowired
private SpellChecker spellChecker;
public TextEditor() {
System.out.println("Inside TextEditor constructor." );
}
public SpellChecker getSpellChecker( ){
return spellChecker;
}
public void spellCheck(){
spellChecker.checkSpelling();
}
}
<bean id="textEditor" class="com.tutorialspoint.TextEditor">
</bean>
<bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
</bean>
构造函数中的 @Autowired
你也可以在构造函数中使用 @Autowired。一个构造函数 @Autowired 说明当创建 bean 时,即使在 XML 文件中没有使用 元素配置 bean ,构造函数也会被自动连接。让我们检查一下下面的示例。
即使bean配置是没说明使用的是构造方法,但是构造函数也会自动连接,进行匹配参数注入
@Autowired 的(required=false)选项
默认情况下,@Autowired 注释意味着依赖是必须的,它类似于 @Required 注释,然而,你可以使用 @Autowired 的 (required=false) 选项关闭默认行为。
即使你不为 age 属性传递任何参数,下面的示例也会成功运行,但是对于 name 属性则需要一个参数。你可以自己尝试一下这个示例,因为除了只有 Student.java 文件被修改以外,它和 @Required 注释示例是相似的。
@Autowired(required=false)
public void setAge(Integer age) { this.age = age; }
@Autowired
public void setName(String name) { this.name = name; }
Spring @Qualifier 注释
可能会有这样一种情况,当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,你可以使用 @Qualifier 注释和 @Autowired 注释通过指定哪一个真正的 bean 将会被装配来消除混乱。下面显示的是使用 @Qualifier 注释的一个示例。
@Autowired
@Qualifier("student1")
private Student student;
基于 Java 的配置
到目前为止,你已经看到如何使用 XML 配置文件来配置 Spring bean。如果你熟悉使用 XML 配置。
基于 Java 的配置选项,可以使你在不用配置 XML 的情况下编写大多数的 Spring,但是一些有帮助的基于 Java 的注解,解释如下:
@Configuration 和 @Bean 注解
带有 @Configuration 的注解类表示这个类可以使用 Spring IoC 容器作为 bean 定义的来源。@Bean 注解告诉 Spring,一个带有 @Bean 的注解方法将返回一个对象,该对象应该被注册为在 Spring 应用程序上下文中的 bean。最简单可行的 @Configuration 类如下所示:
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld(){
return new HelloWorld();
}
}
带有 @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();
}
@Import 注解:
@import 注解允许从另一个配置类中加载 @Bean 定义。考虑 ConfigA 类,如下所示:
@Configurationpublic class ConfigA {
@Bean
public A a() {
return new A();
}
}
可以在另一个 Bean 声明中导入上述 Bean 声明,如下所示:
@Configuration@Import(ConfigA.class)public class ConfigB {
@Bean
public B a() {
return new A();
}
}
现在,当实例化上下文时,不需要同时指定 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 的初始化方法和销毁方法的属性:
@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();
}
}