Spring装配bean

Spring有三种装配机制:
1. 在XML文件进行显示配置
2. 在Java中进行显示配置
3. 隐式的bean发现机制和自动装配

自动化装配bean

使得bean可以被发现

public interface CompactDisc {
    void play();
}
@Component
public class SgtPeppers implements CompactDisc{

    private String title="title";
    private String artist="artist";

    @Override
    public void play() {
        System.out.println("Playing "+title+" by "+artist);
    }
}

在类上使用@Component注解, 这个注解表明该类会作为组件类.

 开启组件扫描

Java开启组件扫描

在类前添加@ComponentScan注解, 即可开启组件扫描, 默认扫描本类所在的包及其子包, 查找所有带@Component注解的类.

@Configuration
@ComponentScan
public class CDPlayerConfig {
}

扫描其它的包

可以给ComponentScan添加相关的属性来自定义需要扫描的包:

  1. ComponentScan(“packageName”)
  2. ComponentScan(basePackage={“package1”,”package2”})
  3. ComponentScan(basePackageClasses={Class1.class,CLass2.class})

方案1将扫描指定包名, 方案2将扫描指定的多个包及其子包, 方案3将扫描这个几个类所在的包及其子包. 在第三种方法中, 我们可以在包中添加一个空的接口, 然后使用该接口来作为扫描的标记.

XML文件开启组件扫描
<context:component-scan base-package="packageName"/>

添加注解自动装配

@Autowired
public void setCompactDisc(CompactDisc cd){
    this.cd = cd;
}

如果没有匹配的bean, 在创建应用上下文时, Spring会抛出一个异常. 可以使用@Autowired(required=false)来避免此异常. 此时, Spring会尝试自动装箱, 但是如果没有匹配的bean时, Spring会让该bean处于未装配的状态. 如果此时调用未装配状态的属性时 可以能会抛出NullPointerException.

Java装配bean

利用JavaConfig来装配bean是比较好的方案. 相对于使用XML文件来装配bean, 它更为强大, 类型安全且更便于重构.

创建配置类

创建配置类, 为类添加@Configuration的注解.

@Configuration
public class BeanConfig{
    ...
}

声明bean

利用JavaConfig来声明bean, 需要编写一个创建所需类型的实例的方法, 并在该方法上添加@Bean注解.

@Bean
public ClassName bean1(){
    return new ClassName();
}

@Bean的注解会告诉Spring该方法会返回一个ClassName实例, 该对象将被注册为bean, 方法体中包含了最终产生的bean的具体方法.

该bean的ID默认即为方法名, 当然可以使用@Bean(name="id")自定义bean的id.

@Bean
public Class1 classBean1(){
    return ...;
}

public ClassName bean1(){
    return new ClassName(classBean1);
}


public ClassName bean2(){
    return new ClassName(classBean1);
}

默认情况下, Spring的bean都是单例, 所以当有多个注入方法中都使用到了classBean1方法的时候, 事实上传入bean1和bean2方法中的Class1实例为同一个.

@Bean
public ClassName bean1(Class1 class1){
    return new ....;
}

在这里, bean1方法请求了一个Class1参数. 当Spring调用bean1方法来创建一个ClassName bean的时候, 会自动地装配一个Class1到该方法中. 这种方法是比较好的, 使用这种方法, 它不会要求Class1也在同一个配置类中声明. Spring可以自动扫描多个JavaConfig类, 甚至XML文件来实现这种装配.

XML装配bean

XML在Spring早期是描述配置的主要书写方式, 但是现在更因为依赖于自动化配置和依赖Java的配置. 一个很主要的原因即在于, 使用XML文件来配置时, 大量的class属性是以字符串形式来保存的, 并不能在编译期间接受类型检查. 不过可以利用IDE的自动感知功能来确保XML配置中类型的正确.

最基本的XML配置文件如下:


声明一个简单的bean

可以按照如下方式声明bean:

<bean class="ClassName" />

可以向这个bean添加id:

<bean id="id" class="ClassName" />

构造器注入初始化bean

两种方案来构建构造器注入:
1. <construct-arg>元素
2. c-命名空间

在大部分情况下, 这两种方式基本上是相同的, 但是对于部分情况, 只有<construct-arg>能够做到(例如注入集合).

构造器注入bean引用
<bean id="id" class="ClassName"
    <construct-arg ref="bean1"/>
</bean>

创建一个ClassName实例,其中将一个ID为bean1的bean引用传递到ClassName的构造器中.

使用c-命名空间:

<bean id="id" class="ClassName"
    <c:arg-ref="bean1"/>
</bean>

<bean id="id" class="ClassName"
    <c:_0-ref="bean1"/>
</bean>

<bean id="id" class="ClassName"
    <c:_-ref="bean1"/>
</bean>
  1. 其中c:表示c-命名空间前缀, arg是构造器中相应的参数名称, -ref表示注入的是bean引用. bean1为要注入的bean的ID.
  2. 也可以使用参数在参数列表中的位置来注入bean, _0, _1 …来表示对应的参数
  3. 如果只有一个参数, 可以只使用_
构造器注入字面量
public ClassName(String title, String artist){
    ...
}
<bean id="id" class="ClassName"
    <construct-arg value="some strings"/>
    <construct-arg value="some strings"/>
</bean>

使用c-命名空间:

<bean id="id" class="ClassName"
    <c:_title="some strings"/>
    <c:_artist="some strings"/>
</bean>

<bean id="id" class="ClassName"
    <c:_0="some strings"/>
    <c:_1="some strings"/>
</bean>

与装配bean引用的区别就在与删除了最后的-ref. 如果只有一个参数, 同样可以使用 _ .

构造器注入集合
public ClassName(String title, String artist, List<String> tracks){
    ....
}
<bean id="id" class="ClassName"
    <construct-arg value="some strings"/>
    <construct-arg value="some strings"/>
    <construct-arg>
        <list>
            <value>some strings</value>
            <value>some strings</value>
            <value>some strings</value>
        </list>
    </construct-arg>
</bean>

如果bean引用的list的话, 将value改为ref即可. 如果需要使用集合, 将list改为set即可.

属性注入初始化bean

@Autowired
public void setSomeArg(Class1 arg1){
    ...
}
<bean id="id" ClassName="ClassName">
    <property name="someArg" ref="bean1" />
</bean> 

<property>元素为属性的Setter方法提供的功能与<construct-arg>元素为构造器所提供的功能是一样的, 用法也类似, 同样可以使用p-命名空间来代替.

<bean id="id" ClassName="ClassName">
    <p:someArg-ref="bean1" />
</bean> 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值