您的位置:首页 > 编程语言 > Java开发

跟着柴毛毛学Spring(3)——简化Bean的配置

2016-04-01 19:30 555 查看


通过前面的学习,我们会感觉到对于一个有较多Bean的大项目,Spring的配置会比较复杂。那么接下来我们就介绍如何简化Spring的配置。

简化Spring的配置主要分为两类:

1. 自动装配

2. 自动扫描

下面就详细介绍这两种简化配置的方式。

自动装配

自动装配的种类

byName:根据属性的名字自动装配

byType:根据属性的类型自动装配

constructor:根据构造器的参数类型自动装配

autodetect:最佳自动装配。首先采用constructor自动装配,若没有发现与构造器相匹配的Bean时,采用byType进行自动装配。

使用XML实现自动装配

byName:根据属性的名字装配

在bean标签中添加属性autowire=”byName”。当Spring启动时,会寻找与person中成员变量名字相同的bean,并将该bean注给person的成员变量。

<bean id="person" class="com.njupt.Person" autowire="byName">
</bean>


byType:根据属性的类型装配

在bean标签中添加属性autowire=”byName”。当Spring启动时,会寻找与person中成员变量类型相同的bean,并将该bean注给person的成员变量。

<bean id="person" class="com.njupt.Person" autowire="byType">
</bean>


byType的缺点:如果某一类型的bean有多个,那Spring在通过byType为属性寻找同类型的bean时就会抛出异常。

解决方案:

- 为相同类型的bean设置是否首选

在需要被首选的bean中作如下设置:

<bean id="person" class="com.njupt.Person" primary="true">
</bean>


在不需要被首选的bean中作如下设置:

<bean id="person" class="com.njupt.Person" primary="false">
</bean>


取消某一些相同类型bean的候选资格

使用auto-candidate属性取消某些bean的候选资格,Spring在为属性寻找同类型的bean时直接排除这些bean。

<bean id="person" class="com.njupt.Person" default-candidate="false">
</bean>


constructor:根据构造器的参数的类型装配

autowire设置为constructor后,Spring会寻找与构造函数的参数类型相同的bean,并注入给这个构造函数。

<bean id="person" class="com.njupt.Person" autowire="constructor">
</bean>


构造器的自动装配本质上仍是通过byType进行装配,只不过autowire=”constructor”时,Spring会对构造器的参数进行自动装配,而autowire=”byType”时,Spring会对bean的成员变量进行自动装配。

构造器的自动装配和byType自动装配具有相同的缺点:当某一类型的bean有多个时,Spring无法确定究竟选择哪个bean,就直接抛出异常。

此外,构造器的自动装配还有个独特的缺点:当构造器有多个时,Spring也无法选择究竟初始化哪个构造器,因此也直接跑出异常。

autodetect:最佳自动装配。Spring要初始化一个设置了autowire=”autodetect”的bean时,首先采用构造器装配,若没有发现与构造器相匹配的Bean或构造器有多个时,就采用byType对属性进行装配。

使用默认自动装配

上述自动装配的方法都是针对单个bean,如果要让beans下的所有bean均使用某种自动装配策略,那么在beans标签中增加如下配置:

default-autowire="byType"


注意1:在beans中设置了default-autowire后,这个参数仅对当前beans标签之间的bean有效。

注意2:采用默认自动装配后,仍然可以在bean中设置特有的自动装配策略,bean中的自动装配策略会覆盖默认策略。

注意3:使用了自动装配后,我们仍然可以在bean中通过constructor-arg属性和property属性对bean进行显示装配。

这种混合使用显示装配和自动装配的方式能够成功地解决byType出现的不确定性问题

注意4:如果使用了constructor来实现构造器参数的自动装配,那么就不能混合使用autowire=”constructor”属性和constructor-arg标签。

使用注解实现自动装配

使用注解装配其实就是把原本XML中bean中的autowire=”xxx”属性搬到了Bean类的Java代码中了。功能上没啥差别。

下面就来介绍如何使用注解实现自动装配。

1. 开启注解自动装配

在beans中作如下配置:

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

</beans>


2. 使用@Autowired标注需要自动装配的函数或属性

当Bean中的属性、函数被标记@Autowired后,Spring在创建这个bean的对象时,会通过byType寻找与属性、函数参数相同类型的bean进行自动装配。

- 用@Autowired标注构造函数

@Autowired
public Person(String name,long id){
this.name = name;
this.id = id;
}


用@Autowired标注普通函数

@Autowired
public void createInstance(){
System.out.println("对象被创建啦!");
}


用@Autowired标注属性

@Autowired
private Father father;


@Autowired本质上采用byType进行自动装配,因此也存在与byType一样的问题:若同一类型的bean有多个时,或找不到该类型的bean,Spring就会抛出异常。

@Autowired弊端的应对策略

若同一类型的bean有多个

若采用xml设置bean的自动装配,则可以使用显示装配的方式,手动设置需要注入的参数,而使用注解自动装配时,可以使用@Qualifier缩小候选bean的范围,具体操作如下:

@Autowired
@Qualifier("father")
private Father father;


@Qualifier(“ID”)会根据bean的id为father装配。

若找不到某一类型的bean

如果bean中的某些属性、参数不需要初始化值也能接受的话,那就为该属性或参数的@Autowired添加required属性:

@Autowired(required="false")
public Person(String name,long id){
this.name = name;
this.id = id;
}


此时,如果Spring找不到与构造函数的参数相同类型的bean的话,就赋上null。

注意:若一个bean有多个构造函数时,只有一个构造函数可以设为@Autowired(required=true),其余的构造函数都只能设为@Autowired(required=false)

在注解中使用SpEL表达式

通过前面学习我们知道,在Spring的XML配置中,可以使用SpEL表达式来实现手动装配。同样,在注解中也可以使用SpEL表达式实现手动装配。

- 将名为father的bean注入给构造函数:

@Value("#{father}")
public Person(Father father){
this.father = father;
}


将father对象中的id注入给id:

@Value("#{father.id}")
public void setId(long id){
this.id = id;
}


自动检测

自动装配能够减少bean标签下property标签和constructor-arg标签的数量,而自动检测能降低bean标签的数量。

1. 开启Spring的自动检测

腰开启自动检测功能,需要在XML的beans标签中作如下配置:

- base-package: 表示要扫描的包

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.5.xsd"> 
<context:component-scan base-package="com.xxx"></context:component-scan>

</beans>


2. 为需要自动减的bean添加@Component注解

要让一个Java类变成一个Bean,需要在类上加上@Component注解。Spring在启动的时候会到base-package指定的包下寻找被@Component标记的类,把他们初始化为bean,保存在SpringContext中。

- 将类型的小写作为bean的名字:

@Component
class Person{
}


指定bean的名字:

@Component("person")
class Person{
}


3. 过滤被扫描的bean

使用Java代替XML配置

虽然使用注解已经大大减少Spring中的XML配置,但仍然需要少量的XML配置,我们可以将XML配置用Java代码实现,从而完全避免了XML配置。

1. 定义一个Spring配置类

用@Configuration标签标注一个类,表示这个类是Spring的配置类:

@Comfiguration
class Person{
……
}


2. 声明一个bean

在Spring的配置类中,使用@Bean标签标注一个bean。

- 函数名:bean的id

- 返回值:bean的类型

- 函数体:初始化这个bean

@Comfiguration
class Person{
@Bean
public Person person(){
//构造器注入
Person person = new Person("柴毛毛");
//属性注入
person.setAge(22);
return person;
}
}


3. 使用Java进行注入

在采用Java进行Spring的配置中,对bean属性和构造器的注入非常简单,只需在函数中操作即可:

@Comfiguration
class Person{
@Bean
public Person person(){
return new Person();
}
}


采用Java代替XML配置的好处

在XML配置中,bean的类型是用String表示的,因此只有在运行结点才能发现bean的类型是否写错;而在Java配置中,在编译阶段就能发现bean的类型是否出错,从而能够尽早地发现错误。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: