Spring总结(2)

Spring 装配Bean

创建应用对象之间协作关系的行为通常称为装配(wiring),这也是依赖注入(DI)的本质

三种装配机制

  • 在XML中进行显式配置
  • 在Java中进行显式配置
  • 隐式的bean发现机制和自动装配

自动化装配

这里写图片描述

  • 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean
// 启动自动扫描
@Configuration
@ComponentScan  // 默认扫描当前的java配置类下的包
public class CDPlayerConfig {}

// 定义javabean
public interface CompactDisc {
    void play();
}

// 实现类并声明组件
@Component("peppersBean")   // peppersBean为当前bean指定id名称
public class SgtPeppers implements CompactDisc{
	 /**
     * @Component:该类会作为组件类,并告知Spring要为这个类创建bean,前提是要启动扫描器
     * Spring应用上下文中所有的bean都会给定一个ID:将类名的第一个字母变为小写,即sgtPeppers
     * 自定义指定bean的Id:@Component(idName)
     * 也可以通过@Named注解来为bean设置ID,但是命名不好,不推荐使用
     */
    @Override
    public void play() {
        System.out.println(String.format("playing %s by %s",title,artist));
    }
}
  • 自动装配(autowiring):Spring自动满足bean之间的依赖
// 启动spring测试类测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)
public class CDPlayerTest {
    /**
     * SpringJUnit4ClassRunner:在测试开始的时候自动创建Spring的应用上下文
     * 注解@ContextConfiguration:告诉它需要在CDPlayerConfig中加载配置
     */

    /**
     * @Autowired:自动装配依赖的bean,即Spring自动满足bean依赖的一种方法,在满足依赖的过程中,会在 Spring应用上下文中寻找匹配某个bean需求的其他bean
     * 如果没有匹配的bean,那么在应用上下文创建的时候,Spring会抛出一个异常。为了避免异常的出现,你可以将@Autowired的required属性设置为false
     * 如果有多个bean都能满足依赖关系的话,Spring将会抛出一个异常,表明没有明确指定要选择哪 个bean进行自动装配
     */

    @Autowired
    private CompactDisc compactDisc;

    @Autowired
    private MediaPlayer cdPlayer;

    @Test
    public void testCompactDiscNotNull(){
        assertNotNull(compactDisc);
    }
}

基于Java显式的配置

// CDPlayer.java
@Configuration
@ComponentScan(basePackageClasses = {CompactDisc.class})
public class CDPlayerConfig {

    /**
     * @ComponentScan:注解能够在Spring中启用组件扫描,默认会扫描与配置类相同的包,即会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类
     * 为何设置基础包:有一个原因会促使我们明确地设置基础包,那就是我们想要将配置类放在单独的包中,使其与其他的应用代码区分开
     * 使用String设置组件扫描的基础包:
     *      单个:basePackages = "com.dtrees.spring.bean"
     *      多个:basePackages = {"com.dtrees.spring.bean","com.dtrees.spring.bean2",...}
     * 使用Class来设置组件扫描的基础包(推荐):
     *      basePackageClasses = {},basePackageClasses属性所设置的数组中包含了类,这些类所在的包将会作为组件扫描的基础包
     */

    // 声明简单的bean并指定bean的id名称
    @Bean(name = "sgtPeppers")
    public CompactDisc getCompactDisc(){
        return new SgtPeppers();
    }
}

Java配置和xml配置混合

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

 <bean id="compactDisc" class="com.dtrees.spring.bean.SgtPeppers"></bean>
</beans>

Java配置

//beans.xml在maven项目的resources目录
@Import(CDConfig.class)
@ImportResource("classpath:beans.xml")	
public class CDPlayerConfig {
	/**
     * @Import({}):将多个配置类进行组合一起
     * @ImportResource("classpath:beans.xml"):将spring配置的xml组合在一起
     */
@Bean(name = "cdPlayer")
public MediaPlayer getMediaPlayer(CompactDisc compactDisc){
        return new CDPlayer(compactDisc);
    }
}

spring装配的命名空间

## 开头省略...
<!-- 
c-命名空间来声明构造器参数
beans.xml中必须引入xmlns:c="http://www.springframework.org/schema/c"的声明
-->
<!--
        使用命名
        c:compactDisc-ref="sgtPeppers1"
        属性名称c:命名空间的前缀
        compactDisc:装配的构造器参数名
        -ref:这是一个命名的约定,它会告诉Spring,正在装配的是一个bean的引用,这个bean的名字是compactDisc,而不是字面量“compactDisc”
        sgtPeppers1:要注入的bean的ID名称
    -->
<bean id="cdPlayer2" class="com.dtrees.spring.bean.CDPlayer" c:compactDisc-ref="sgtPeppers1"></bean>

使用属性的命名空间

 <!--
        使用属性命名空间(p-命名空间的属性):
        p:title-ref="title-ref"
        属性的名字使用了“p:”前缀,表明我们所设置的是一个属性
        "title":接下来就是要注入的属性名。
        -ref:这会提示Spring要进行装配的是引用,而不是字面量
        title-ref:要注入的bean的ID名称
    -->
// 引入属性的命名空间xmlns:p="http://www.springframework.org/schema/p"

//设置字面值
<bean id="compactDisc" class="com.dtrees.spring.bean.SgtPeppers" p:title="xxx value"></bean>

// 设置引用
<bean id="compactDisc" class="com.dtrees.spring.bean.SgtPeppers" p:title-ref="title-ref"></bean>

小结:c与p的命名空间,在装配bean引用与装配字面量的唯一区别在于是否带有“-ref”后缀,如果没 有“-ref”后缀的话,所装配的就是字面量

bean的注入方式(这里只用JavaConfig注入方式,不用xml配置)

@Component
public class CDPlayer implements MediaPlayer{

    private CompactDisc compactDisc;

    // 通过构造器自动装配
    @Autowired
    public CDPlayer(CompactDisc compactDisc){
        this.compactDisc = compactDisc;
    }

    // 通过设置器自动装配
    @Autowired
    public void setCompactDisc(CompactDisc compactDisc){
        this.compactDisc = compactDisc;
    }

    // 其他方法
    @Autowired
    public void insertCompactDisc(CompactDisc compactDisc){
        this.compactDisc = compactDisc;
    }

    public CompactDisc getCompactDisc(){
        return this.compactDisc;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疾风先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值