Spring(一)装配Bean

来源:互联网 发布:网络机柜接线图视频 编辑:程序博客网 时间:2024/06/01 10:08

Spring有三种装配方式:
1.XML显示装配
2.java注释
3.自动装配
创建可被发现的bean

java注释:

package soundsystem;public interface CompactDisc {    void play();}
package soundsystem;import org.springframework.stereotype.Component;@Componentpublic class SgtPeppers implements CompactDisc{    String title = "pipa  pilipala";    public void play() {        System.out.println("CD play:"+title);    }}

使用了@Component注解。这个简单的注解表明该类会作为组件类,并
告知Spring要为这个类创建bean
不过,组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带
有@Component注解的类,并为其创建bean。程序清单2.3的配置类展现了完成这项任务的最
简洁配置。

package soundsystem;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;@Configuration@ComponentScanpublic class CDPlayerConfig {}

@ComponentScan注解,这个注解能够在Spring中启用
组件扫描。
如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包。因
为CDPlayerConfig类位于soundsystem包中,因此Spring将会扫描这个包以及这个包下
的所有子包,查找带有@Component注解的类。这样的话,就能发现CompactDisc,并且
会在Spring中自动为其创建一个bean。

使用XML装配Bean

<?xml version="1.0" encoding="UTF-8"?><!--  Licensed to the Apache Software Foundation (ASF) under one or more  contributor license agreements.  See the NOTICE file distributed with  this work for additional information regarding copyright ownership.  The ASF licenses this file to You under the Apache License, Version 2.0  (the "License"); you may not use this file except in compliance with  the License.  You may obtain a copy of the License at      http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software  distributed under the License is distributed on an "AS IS" BASIS,  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and  limitations under the License.--><!-- @version $Id: applicationContext.xml 561608 2007-08-01 00:33:12Z vgritsenko $ --><beans xmlns="http://www.springframework.org/schema/beans"        xmlns:context="http://www.springframework.org/schema/context"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:util="http://www.springframework.org/schema/util"       xmlns:configurator="http://cocoon.apache.org/schema/configurator"       xmlns:avalon="http://cocoon.apache.org/schema/avalon"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd                           http://cocoon.apache.org/schema/configurator http://cocoon.apache.org/schema/configurator/cocoon-configurator-1.0.1.xsd                           http://cocoon.apache.org/schema/avalon http://cocoon.apache.org/schema/avalon/cocoon-avalon-1.0.xsd"> <context:component-scan base-package="soundsystem"/>  <!-- Activate Cocoon Spring Configurator -->  <configurator:settings/>  <!-- Configure Log4j -->  <bean name="org.apache.cocoon.spring.configurator.log4j"        class="org.apache.cocoon.spring.configurator.log4j.Log4JConfigurator"        scope="singleton">    <property name="settings" ref="org.apache.cocoon.configuration.Settings"/>    <property name="resource" value="/WEB-INF/log4j.xml"/>  </bean>  <!-- Activate Avalon Bridge -->  <avalon:bridge/></beans>

为了测试组件
扫描的功能,我们创建一个简单的JUnit测试,它会创建Spring上下文,并判断
CompactDisc是不是真的创建出来了。
测试组件扫描能够发现CompactDisc

package soundsystem;import static org.junit.Assert.assertNotNull;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes= CDPlayerConfig.class)public class CDPlayerTest {    @Autowired    private CompactDisc cd ;     @Test    public void CDShouldNotBeanNull(){        System.out.println(cd);        assertNotNull(cd);    }}

若测试不报错即可
注解@ContextConfiguration会告诉它需要
在CDPlayerConfig中加载配置。因为CDPlayerConfig类中包含了
@ComponentScan,因此最终的应用上下文中应该包含CompactDiscbean。

为组件扫描的bean命名

@Component("lonelyHeartsClub")public class SgtPeppers implements CompactDisc{}

设置组件扫描的基础包

@Configuration@ComponentScan("soundsystem")public class CDPlayerConfig {}``如果你想更加清晰地表明你所设置的是基础包,那么你可以通过basePackages属性进行配置:`

@Configuration
@ComponentScan(basePackages=”soundsystem”)
public class CDPlayerConfig {
}

可能你已经注意到了basePackages属性使用的是复数形式。如果你揣测这是不是意味着可以设置多个基础包,那么恭喜你猜对了。如果想要这么做的话,只需要将basePackages属性设置为要扫描包的一个数组即可:

@Configuration
@ComponentScan(basePackages={“soundsystem”,”video”})
public class CDPlayerConfig {
}

在上面的例子中,所设置的基础包是以String类型表示的。我认为这是可以的,但这种方法是类型不安全(not type-safe)的。如果你重构代码的话,那么所指定的基础包可能就会出现错误了除了将包设置为简单的String类型之外,@ComponentScan还提供了另外一种方法,那就是将其指定为包中所包含的类或接口:

@Configuration
@ComponentScan(basePackageClasses={cdplay.class,dvdplay.class})
public class CDPlayerConfig {
}

@Component
public class CDplayer implements MediaPlayer {
@Autowired
private CompactDisc cd;
public CDplayer(CompactDisc cd){
this.cd = cd;
}
public void play(){
cd.play();
}
@Autowired
public void setCompactDisc(CompactDisc cd){

}

}

@Autowired注解不仅能够用在构造器上,还能用在属性的Setter方法上。比如说,如果CDPlayer有一个setCompactDisc()方法,那么可以采用如下的注解形式进行自动装配在Spring初始化bean之后,它会尽可能得去满足bean的依赖,在本例中,依赖是通过带有@Autowired注解的方法进行声明的,也就是setCompactDisc()。实际上,Setter方法并没有什么特殊之处。@Autowired注解可以用在类的任何方法上。假设CDPlayer类有一个insertDisc()方法,那么@Autowired能够像在setCompactDisc()上那样,发挥完全相同的作用:将required属性设置为false时,Spring会尝试执行自动装配,但是如果没有匹配的bean的话,Spring将会让这个bean处于未装配的状态。
@Autowired(required = false)public CDplayer(CompactDisc cd){    this.cd = cd;}

“`

但是,把required属性设置为false
时,你需要谨慎对待。如果在你的代码中没有进行null检查的话,这个处于未装配状态的属
性有可能会出现NullPointerException。
如果有多个bean都能满足依赖关系的话,Spring将会抛出一个异常,表明没有明确指定要选
择哪个bean进行自动装配

@Autowired是Spring特有的注解。如果你不愿意在代码中到处使用Spring的特定注解来完
成自动装配任务的话,那么你可以考虑将其替换为@Inject