SpringInAction 4 笔记——(一)Spring配置方案

【Spring配置方案】

选择:

a.优选使用自动配置的机制,显示配置越少越好;

b.如果一定要显式配置建议使用JavaConfig;

c.最后才是XML配置


1.在XML中进行显式配置;

   这个应该是最常用的,虽然它不是最佳选择,但是它在Spring中存在的历史已经很长了。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/bean 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

    <!-- 配置文件 -->
	
</beans>

<bean>元素类似于JavaConfig中的@Bean,声明一个CompactDisc bean:

<bean id="compactDisc" class="soundsystem.SgtPeppers" />

注意,要采用类的全限定的类名

Spring发现<bean>元素时,会调用SgtPeppers的默认构造函数来创建bean,而JavaConfig可以通过构造器,setter方法和其他方法来创建。

如何借助构造器注入初始化bean?

a.<constructor-arg>元素

b.使用c-命名空间

eg:用构造器将CompactDisc注入SgtPeppers bean中

上面已经声明了一个SgtPeppers bean ,而SgtPeppers类实现了CompactDisc,所以:

<bean id="cdPlayer" class="soundsystem.CDPlayer">
    <comstructor-arg ref="compactDisc" />
</bean>

使用c-命名空间,要在配置文件中加入:

xmlns:c="http://www.springframework.org/schema/c"

<bean id="cdPlayer" class="soundsystem.CDPlayer" c:cd-ref="compactDisc" />
上面的cd是指构造器参数的名称,这种方式有点怪异,当然也可以用参数的索引来代替,如下:
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_0-ref="compactDisc" />
如果构造器只有一个参数,可以改为:
<bean id="cdPlayer" class="soundsystem.CDPlayer" c:_-ref="compactDisc" />
参数虽然可以写任意值,但是这也是硬编码的,稍后我会在笔记二中引入非硬编码的属性占位符和SpEL。可以如下:
<bean id="compactDisc" class="soundsystem.BlankDisc">
    <constructor-arg value="第一个参数的值"/>
    <constructor-arg value="第二个参数的值"/>
</bean>
<bean id="compactDisc" class="soundsystem.BlankDisc">
    c:_title="参数title的值"
    c:_artist="参数artist的值"/>
<bean id="compactDisc" class="soundsystem.BlankDisc">
    c:_0="参数title的值"
    c:_1="参数artist的值"/>

注意:用c-命名空间无法实现装配集合功能。eg:list   set

可以用<constructor-arg>:

<constructor-arg>
    <list>
        <value>元素1</value>
        <value>元素2</value>    
    </list>
</constructor_arg>
<constructor-arg>
    <set>
        <value>元素1</value>
        <value>元素2</value>    
    </set>
</constructor_arg>

Spring XML 是如何实现属性注入的?

可以通过setter方法:

<bean id="CDPlayer" class="soundsystem.CDPlayer">
    <property name="compactDisc" ref="compactDisc">
</bean>

构造器注入用<constructor-arg>

setter方法用<property>

相对的,构造器注入有c-命名空间,而setter方法有p-命名空间

xmlns:p="http://www.springframework.org/schema/p"

<bean id="cdPlayer" class="soundsystem.CDPlayer" p:compactDisc-ref="compactDisc" />

第一个compactDisc是属性名

什么是字面量?eg:

        int i = 1;把整数1赋值给int型变量i,整数1就是Java字面量,

        同样,String s = "abc";中的abc也是字面量。

装配bean引用与装配字面量的唯一区别是是否带有“-ref”

eg:

p:compactDisc-ref="compactDisc"

P:title="title参数的字面量值";

注意:用p-命名空间无法实现装配集合功能。eg:list   set

可以用util-命名空间 :

xmlns:util="http://www.springframework.org/schema/util"

<util:list id="">
    <value>元素1</value>
    <value>元素2</value>    
</util:list>

<util:constant>

<util:list>

<util:map>

<util:properties>

<util:property-path>

<util:set>

对于构造器注入和属性注入的选择:强依赖使用构造器注入,可选性依赖选择属性注入


2.在JavaConfig中进行显示配置;

        当用到第三方库中的组件时自动化配置行不通,要用到显示声明

        JavaConfig尽管是java代码,但又与其他java代码有所不同,它是配置代码。通常单独放置一个包中,使它与其他业务逻辑分离。

        @Configuration注解过的类:表明这个类是一个配置类。

@Configuration
public class CDPlayerConfig{
    
}

        但是这里移除了@ComponentScan注解,此时的CDPlayerConfig类就没有任何作用了,如果想注入CDPlayer和CompactDisc也不可能,这些bean根本没有创建,因为组件扫描不会发现它们。那如何利用JavaConfig显式声明bean呢?

           答:用@Bean注解。@Bean注解表明这个方法会创建一个bean实例并将其注册到Sprin应用上下文中

  //bean的ID默认为与带有@Bean注解的方法名一致,即本实例的ID为sgtPeppers
@Bean
public CompactDisc sgtPeppers{
    return new SgtPeppers();
}
//若想自取ID名,可以如下
@Bean(name="bean的ID名称")
public CompactDisc sgtPeppers{
    return new SgtPeppers();
}

如果想创建一个依赖于其他bean的bean该如何创建?比如说要声明一个CDPlayer的bean,这个bean依赖于CompactDisc

@Bean
public CDPlayer cdPlayer{
    return new CDPlayer(sgtPeppers());
}

这里没有使用默认的构造器来构建实例,而是使用了需要传入CompactDisc对象的构造器。

注意,这里不是通过调用sgtPeppers()得到的。如果使用了@Bean注解,Spring会拦截所有对这个方法的调用,确保返回的是该方法所创建的bean,而不是每次都对其进行实际的调用。也就是说sgtPeppers是不可变的,无论多少个方法注入它,它始终返回它所创建的bean。

如果难以理解,可用下面一种方法(建议使用):

@Bean
public CDPlayer cdPlayer(COmpactDisc compactDIsc){
    return new CDPlayer(compactDisc);
}

使用这种方法Spring会自动装配一个CompactDisc到配置方法中(即被@Configuration注解的方法),然后,方法体就可以按照合适的方式来使用它。这种方法不用明确引用CompactDisc的@Bean方法。

这个方法优点:它不会要求CompactDisc声明到同一个配置类中,它甚至可以通过组件扫描或者XML来进行配置。无论CompactDisc是采用什么方式创建出来的,Spring都会将其传入到配置方法中,并用来创建CDPlayer bean

当然,除了用构造方法来实现DI功能,还可以用Setter方法来实现:

@Bean
public CDPlayer cdPlayer(CompactDisc compactDisc){
    CDPlayer cdPlayer = new CDPlayer(compactDisc);
    cdPlayer.setCompactDisc(compactDisc);
    return cdPlayer;
 }

3.隐式的bean发现机制和自动装配。

        组件扫描(component scanning):

               1. 注解:@Component  @Service @Repository @Controller 标志该类为组件类

               2.启用组件扫描:

                            a.注解型:@ComponentScan注解启用组件扫描;

                                            eg:

@configuration
@ComponentScan
public class CDPlayerConfig{

}

 在创建spring应用上下文时要加载bean必须加载配置: @contextConfiguration(classes=CDPlayerConfig.class); 

 如果ComponentScan没有指定任何属性,默认是扫描基础包

 也可以指定要扫描的包:

eg:

@ComponentScan("包的名称") 或 @ComponentScan(basePackages="包的名称")   

扫多个:@ComponentScan(basePackages="包的名称1","包的名称2")   

上面方法存在一定安全隐患,如果重构代码可能会出错,可以改为:

@ComponentScan(basePackageClasses={CDPlayer.class,DVDPlayer.class}) 

这些类所在的包将会作为组件扫描的基础包。

                         

                            b.XML型:<context: component-scan base-package="">


        自动装配(autowiring):

                自动装配就是让Spring自动满足bean依赖的一种方法,Spring应用上下文中寻找匹配的某个bean需求的其他bean;

                 需要借助注解:@Autowired

                这个注解可以用在类的任何方法上,如构造方法,setter方法,普通方法或者对象上等等

               使用@Autowired时,如果Spring应用上下文中没有匹配的bean,Spring会抛出一个异常,为了避免,

                可以将@Autowired中的属性required设置为false,改为:

                @Autowired(required=false)

                  这时候没有匹配的bean的话Spring就会将这个bean处于未装配状态,是null的,但是如果你没有进行null检查的话,处于未匹配状态的属性就有可能会抛出异常NullPointerException.

@Component
public class CDPlayer implements MediaPlayer{
   //构造方法
   @Autowired
   public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }

    //Setter方法
    @Autowired(required=false)
    public void setCompactDisc(CompactDisc cd){
        this.cd = cd;
    }

    //属性上
    @Autowired
    private CompactDisc cd;
 }

        


Spring应用上下文中所有的bean都会给定一个ID,默认将类名的第一个字母变为小写作为ID,另外两种为:

1.@Component("beanID名称")  这个比较常用

2.@Named("beanID名称")











  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值