Spring实战笔记——装配bean

Spring配置的可选方案

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

自动装配

自动装配主要从以下两个方面实现:

  • 组件扫描
  • 自动装配

简单的自动装配代码

1、配置maven

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
      
    <groupId>com.anran.spring</groupId>
    <artifactId>spring-inaction</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.2.8.RELEASE</version>
        </dependency>
    </dependencies>


</project>

2、创建CD接口和接口的实现类

// 接口
package com.ruian;

public interface CompactDisc {
    void play();
}

//实现类
package com.ruian;
import org.springframework.stereotype.Component;

@Component//标注该类为一个bean,默认beanID为类名首字母小写
public class SgtPeppers implements CompactDisc{
    private String title = "Sgt. Pepper's Lonely Hearts Club Band";
    private String artitle = "The Beatles";

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

3、创建CDplayer配置类

package com.ruian;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration//标注该类为一个配置类
@ComponentScan//扫描注解,默认扫描与该类同包的组件(需要有@Component注解)
public class CDPlayerConfig {

}

4、进行测试

package com.ruian;

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;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CDPlayerConfig.class)//导入配置类
public class CDPlayerTest {
    @Autowired
    private CompactDisc cd;

    @Test
    public void cdShouldNotBeNull(){
        assertNotNull(cd);
    }
}

设置命名

@Component:默认将类的首位字母小写作为beanId,可以通过@Component("loneyHeartsClub")设置名称,大多是情况下可以与@Name替换。
@ComponentScan:默认扫描与该类同包的组件,可以通过@ComponentScan("com.ruian")指定扫描的基础包。可以指定多个基础包,如@ComponentScan(basePakages="com.ruian", "com.anran")使用basePakages属性可能导致不安全,比如重构代码可能会修改基础包,因此可以使用basePackageClasses属性指定包中的类或接口,如@ComponentScan(basePackageClasses=CDPlayer.class)不能省略basePackageClasses=。

为bean添加注解实现自动装配

package com.ruian;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

@Component
public class CDPlayer implements MediaPlayer {
    private CompactDisc cd;
    //当Spring创建CDPlayer bean时,会自动注入CompactDisc,设置required属性可以防止当匹配不到bean时spring报错
    @Autowired(required = false)
    public CDPlayer(CompactDisc cd){
        this.cd = cd;
    }
    @Override
    public void play() {
     cd.play();
    }

//    @Autowired(required = false)//也可以对Setter方法注入
//    public void setCd(CompactDisc cd) {
//        this.cd = cd;
//    }
}

使用Java代码装配bean

假设需要使用第三方库中的组件导入自己的应用,无法使用@Component和@Autowired注解,因此需要java代码或XML进行显性装配。

package com.ruian;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration//标注该类为一个配置类
public class CDPlayerConfig {
    //进行显式装配bean
    @Bean//将返回的对象设置为bean对象,默认与方法名相同,也可以利用name属性指定名称
    public CompactDisc sgtPeppers(){
        return new SgtPeppers();
    }
    
    //将cd注入到CDplayer
    @Bean
    public CDPlayer cdPlayer(){
        return new CDPlayer(sgtPeppers());
    }

}

利用xml配置bean

一个简单的Spring Xml配置

<?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/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
     <!-- 注入bean -->
    <bean id = "compactDisc" class="com.ruian.SgtPeppers"/>
    
    <!-- 将CD注入到CDPlayer -->
<!--    <bean id = "cdPlayer" class="com.ruian.CDPlayer">-->
<!--        <constructor-arg ref="compactDisc"/>-->
<!--    </bean>-->
    
    <!-- 使用c-命名空间 -->
    <bean id = "cdPlayer" class="com.ruian.CDPlayer"
        c:cd1-ref="compactDisc">
        
    </bean>
<!-- #####利用构造器注入##### -->
  <!-- 给属性注入字面变量 -->
    <bean id = "cd" class="com.ruian.BlankDisc">
        <constructor-arg value="Sgt. Peooer"/>
        <constructor-arg value="The Beatles"/>
    </bean>

    <!-- C命名空间 -->
    <bean id = "cd1" class="com.ruian.BlankDisc"
    c:_0="Sgt. Peooper"
    c:_1="The Beatles"/>
    <bean id = "cd2" class="com.ruian.BlankDisc"
          c:title="Sgt. Peooper"
          c:artist="The Beatles"/>

    <!-- 注入List集合(无法使用c命名空间) -->
    <bean id = "cd3" class="com.ruian.BlankDisc">
        <constructor-arg value="title"/>
        <constructor-arg value="artist"/>
        <constructor-arg>
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </constructor-arg>
    </bean>

<!-- #####利用Setter方法注入##### -->

<bean id = "cdplayer" class="com.ruian.CDPlayer">
        <property name="cd" ref="compactDisc"/>
    </bean>
    <!-- p命名空间 -->
    <bean id = "cp1" class="com.ruian.CDPlayer"
          p:cd-ref="compactDisc"/>

    <!-- 注入字面量 -->
    <!-- 利用属性注入时如果自定义了有参构造器,需要将无参构造器也添加上去 -->
    <bean id = "cp2" class="com.ruian.BlankDisc">
        <property name="artist" value="atrist"/>
        <property name="title" value="title"/>
        <property name="tracks">
            <list>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </list>
        </property>
    </bean>
    
    <!-- 利用p:命名空间注入list需要借助 util:命名空间 -->
    <util:list id="tracklist">
        <value>1</value>
        <value>2</value>
        <value>3</value>
    </util:list>
    <bean id = "cd4" class="com.ruian.BlankDisc"
          p:artist="artist"
          p:title="title"
          p:tracks-ref="tracklist"/>

</beans>

c-命名空间:c:cd1-ref="compactDisc",c表示前缀,cd1表示构造器的参数,ref表示装配的式bean引用。
c:_0-ref="compactDisc", _0表示构造器的第一个参数。
p-命名空间与c-命名空间相似。

导入混合配置

JavaConfig中导入xml配置文件:@Import()可以导入其他的javaconfig,如@Import(A.class), @Import({A.class, B.class}),@ImportResource()可以导入xml配置文件,如@ImportResource("classpath:A.xml")。
XML配置文件中导入JavaConfig:<import resource="spring.xml"/>导入其他XML配置文件,<bean class="com.ruian.CDPlayerConfig"/>导入JavaConfig

参考文献

Spring实战(第4版)

posted @ 2021-02-06 12:58  梦不是很远  阅读(73)  评论(0)    收藏  举报