Spring
的
IoC
我们来看看上面代码的含义,首先在代码①和②处我们分别定义了两个名为Foo和Bar的Bean,在③处我们通过set方法将两个Bean注入进Base类中,并且在Base类中定义了toString方法来打印出Foo和Bar的信息,在④处我们定义了一个MainClass来执行我们的代码,在⑤处我们通过getBean获得配置文件中配置的id为base的Bean并在⑥出将其信息打印至控制台,控制台输出信息如下:
Base : [The Foo's Name is : Tony The Foo's Age is : 27 The Bar's Address is : China Tianjin]
看到上面习以为常的配置信息和set get方法我们根本不会有任何想法,可是当我们看到了Spring2.5注释特性的时候我们发现自己真的错了,程序竟然还可以写成这么简单。
我们在①和②处使用了@Autowired注释,它可以对类的成员变量、方法及构造函数进行标注,完成自动装配的工作,在③处我们为了使@Autowired注释生效必须在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean它通过扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其相匹配(默认按类型匹配)的 Bean,并将其注入,而此时我们在声明Base的时候(④处)就不用写它的配置信息了,更可以将Base类中的set和get方法删除。@Autowired还可以通过类的构造函数来进行自动装配。
在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean
我们增加了一个构造函数,通过它来对我们的成员变量进行赋值,我们同时也为这个构造函数添加了@Autowired注释(①处)使其可以自动将Foo和Bar两个成员变量装配进来。
当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false),这等于告诉 Spring:在找不到匹配 Bean 时也不报错
①和②处我们分别定义了两个类型为Bar的Bean,②处Bar的address为China Beijing并且Bean的名称为bar2,在代码清单4.2的③处我们同样使用了@Autowired注释为Bar的构造函数进行自动装配,可是在④处我们通过@Qualifier("bar2")来明确指定我们需要将id为bar2的Bean装配进来。我们还可以为成员变量使用@Qualifier注释。
使用了@Autowired注释后我们发现自动注入真的非常简单,但是我们还是得在配置文件中定义相应的<Bean>,如果我们能在配置文件中完全移除Bean的定义那就更好了,Spring2.5就为我们提供了这一可能。
public
class
Foo
{①
private String name;
private int age;
public String toString() {
return " The Foo's Name is : " + this .name + " The Foo's Age is : " + this .age;
}
public String getName() { }
public void setName(String name) { }
public int getAge() { }
public void setAge( int age) { }
}
private String name;
private int age;
public String toString() {
return " The Foo's Name is : " + this .name + " The Foo's Age is : " + this .age;
}
public String getName() { }
public void setName(String name) { }
public int getAge() { }
public void setAge( int age) { }
}
public
class
Bar
{②
private String address;
public String toString() {
return " The Bar's Address is : " + this .address;
}
public String getAddress() { }
public void setAddress(String address) { }
}
private String address;
public String toString() {
return " The Bar's Address is : " + this .address;
}
public String getAddress() { }
public void setAddress(String address) { }
}
public
class
Base
{③
private Foo foo;
private Bar bar;
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
public Foo getFoo() { }
public void setFoo(Foo foo) { }
public Bar getBar() { }
public void setBar(Bar bar) { }
}
private Foo foo;
private Bar bar;
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
public Foo getFoo() { }
public void setFoo(Foo foo) { }
public Bar getBar() { }
public void setBar(Bar bar) { }
}
<?
xml version="1.0" encoding="UTF-8"
?>
< beans xmlns =" " >
< bean id ="foo" class ="com.tony.test.Foo" >
< property name ="name" value ="Tony" />
< property name ="age" value ="27" />
</ bean >
< bean id ="bar" class ="com.tony.test.Bar" >
< property name ="address" value ="China Tianjin" />
</ bean >
< bean id ="base" class ="com.tony.test.Base" >
< property name ="foo" >
< ref local ="foo" />
</ property >
< property name ="bar" >
< ref local ="bar" />
</ property >
</ bean >
</ beans >
< beans xmlns =" " >
< bean id ="foo" class ="com.tony.test.Foo" >
< property name ="name" value ="Tony" />
< property name ="age" value ="27" />
</ bean >
< bean id ="bar" class ="com.tony.test.Bar" >
< property name ="address" value ="China Tianjin" />
</ bean >
< bean id ="base" class ="com.tony.test.Base" >
< property name ="foo" >
< ref local ="foo" />
</ property >
< property name ="bar" >
< ref local ="bar" />
</ property >
</ bean >
</ beans >
import
org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {④
public static void main(String[] args) {
String[] locations = { " spring-config-beans.xml " } ;
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);
Base main = (Base) ctx.getBean( " base " );⑤
System.out.println(main);⑥
}
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainClass {④
public static void main(String[] args) {
String[] locations = { " spring-config-beans.xml " } ;
ApplicationContext ctx = new ClassPathXmlApplicationContext(locations);
Base main = (Base) ctx.getBean( " base " );⑤
System.out.println(main);⑥
}
}
我们来看看上面代码的含义,首先在代码①和②处我们分别定义了两个名为Foo和Bar的Bean,在③处我们通过set方法将两个Bean注入进Base类中,并且在Base类中定义了toString方法来打印出Foo和Bar的信息,在④处我们定义了一个MainClass来执行我们的代码,在⑤处我们通过getBean获得配置文件中配置的id为base的Bean并在⑥出将其信息打印至控制台,控制台输出信息如下:
Base : [The Foo's Name is : Tony The Foo's Age is : 27 The Bar's Address is : China Tianjin]
看到上面习以为常的配置信息和set get方法我们根本不会有任何想法,可是当我们看到了Spring2.5注释特性的时候我们发现自己真的错了,程序竟然还可以写成这么简单。
三、使用
@Autowired
注释
import
org.springframework.beans.factory.annotation.Autowired;
public class Base {
@Autowired① 使用了一个名为Autowired的注释
private Foo foo;
@Autowired②
private Bar bar;
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
}
public class Base {
@Autowired① 使用了一个名为Autowired的注释
private Foo foo;
@Autowired②
private Bar bar;
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
}
<!--
该 BeanPostProcessor 将自动对标注 @Autowired 的 Bean 进行注入
-->
③
< bean class ="org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor" />
< bean id ="foo" class ="com.tony.test.Foo" >
< property name ="name" value ="Tony" />
< property name ="age" value ="27" />
</ bean >
< bean id ="bar" class ="com.tony.test.Bar" >
< property name ="address" value ="China Tianjin" />
</ bean >
<!-- 此时移除了Base的配置信息 --> ④
< bean id ="base" class ="com.tony.test.Base" />
< bean class ="org.springframework.beans.factory.annotation.
AutowiredAnnotationBeanPostProcessor" />
< bean id ="foo" class ="com.tony.test.Foo" >
< property name ="name" value ="Tony" />
< property name ="age" value ="27" />
</ bean >
< bean id ="bar" class ="com.tony.test.Bar" >
< property name ="address" value ="China Tianjin" />
</ bean >
<!-- 此时移除了Base的配置信息 --> ④
< bean id ="base" class ="com.tony.test.Base" />
我们在①和②处使用了@Autowired注释,它可以对类的成员变量、方法及构造函数进行标注,完成自动装配的工作,在③处我们为了使@Autowired注释生效必须在Spring容器中声明AutowiredAnnotationBeanPostProcessor Bean它通过扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有 @Autowired 注释时就找到和其相匹配(默认按类型匹配)的 Bean,并将其注入,而此时我们在声明Base的时候(④处)就不用写它的配置信息了,更可以将Base类中的set和get方法删除。@Autowired还可以通过类的构造函数来进行自动装配。
在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean
import
org.springframework.beans.factory.annotation.Autowired;
public class Base {
private Foo foo;
private Bar bar;
@Autowired
public Base(Foo foo,Bar bar) { ①
this .foo = foo;
this .bar = bar;
}
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
}
public class Base {
private Foo foo;
private Bar bar;
@Autowired
public Base(Foo foo,Bar bar) { ①
this .foo = foo;
this .bar = bar;
}
public String toString() {
return " Base : [ " + this .foo.toString() + " " + this .bar.toString() + " ] " ;
}
}
我们增加了一个构造函数,通过它来对我们的成员变量进行赋值,我们同时也为这个构造函数添加了@Autowired注释(①处)使其可以自动将Foo和Bar两个成员变量装配进来。
当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false),这等于告诉 Spring:在找不到匹配 Bean 时也不报错
四、使用
@Qualifier
注释
有时我们会遇到这样一种情况,我们定义了两个类型相同数据不同的Bean,我们此时需要用到其中一个Bean来供我们使用,使用@Qualifier注释就可以满足我们的要求,当使用@Qualifier注释时自动注入的策略就从 byType 转变成 byName 了。
<
bean
id
="bar"
class
="com.tony.test.Bar"
>
①
< property name ="address" value ="China Tianjin" />
</ bean >
< bean id ="bar2" class ="com.tony.test.Bar" > ②
< property name ="address" value ="China Beijing" />
</ bean >
< property name ="address" value ="China Tianjin" />
</ bean >
< bean id ="bar2" class ="com.tony.test.Bar" > ②
< property name ="address" value ="China Beijing" />
</ bean >
import
org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Base {
private Bar bar;
@Autowired ③
public Base(@Qualifier( " bar2 " )Bar bar) { ④
this .bar = bar;
}
public String toString() {
return " Base : [ " + this .bar.toString() + " ] " ;
}
}
import org.springframework.beans.factory.annotation.Qualifier;
public class Base {
private Bar bar;
@Autowired ③
public Base(@Qualifier( " bar2 " )Bar bar) { ④
this .bar = bar;
}
public String toString() {
return " Base : [ " + this .bar.toString() + " ] " ;
}
}
①和②处我们分别定义了两个类型为Bar的Bean,②处Bar的address为China Beijing并且Bean的名称为bar2,在代码清单4.2的③处我们同样使用了@Autowired注释为Bar的构造函数进行自动装配,可是在④处我们通过@Qualifier("bar2")来明确指定我们需要将id为bar2的Bean装配进来。我们还可以为成员变量使用@Qualifier注释。
import
org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Base {
@Autowired ①
@Qualifier( " bar2 " ) ②
private Bar bar;
public String toString() {
return " Base : [ " + this .bar.toString() + " ] " ;
}
}
import org.springframework.beans.factory.annotation.Qualifier;
public class Base {
@Autowired ①
@Qualifier( " bar2 " ) ②
private Bar bar;
public String toString() {
return " Base : [ " + this .bar.toString() + " ] " ;
}
}
五、使用
@Component
注释
使用了@Autowired注释后我们发现自动注入真的非常简单,但是我们还是得在配置文件中定义相应的<Bean>,如果我们能在配置文件中完全移除Bean的定义那就更好了,Spring2.5就为我们提供了这一可能。
import
org.springframework.stereotype.Component;
@Component ①
public class Bar {
private String address = " China Tianjin " ;
public String toString() {
return " The Bar's Address is : " + this .address;
}
}
@Component ①
public class Bar {
private String address = " China Tianjin " ;
public String toString() {
return " The Bar's Address is : " + this .address;
}
}
import
org.springframework.stereotype.Component;
@Component( " base " ) ②
public class Base {
@Resource
private Bar bar;
public String toString() {
return " Base : [ " + <spa
@Component( " base " ) ②
public class Base {
@Resource
private Bar bar;
public String toString() {
return " Base : [ " + <spa
发表评论
评论