装配Bean

一、声明Bean

创建一个接口:

package cn.edu.stu.springidol;

public interface Performer {
    void perform();
}

实现类:

public class Juggler implements Performer {
    private int beanBags = 3;
    
    public Juggler() {
    }
    
    public Juggler(int beanBags) {
        this.beanBags = beanBags;
    }
    
    @Override
    public void perform() {
        System.out.println("JUGGLING " + beanBags + " BEANBAGS");

    }

}

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"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="duke" class="cn.edu.stu.springidol.Juggler">
        <constructor-arg value="15" />
    </bean>
</beans>

<constructor-arg>配置通过构造器注入参数beanBags=15,如果不配置,默认beanBags=3

运行结果:

通过构造器注入对象引用:

public interface Poem {
    void recite();
}

public class Sonnet29 implements Poem {
    private static String[] LINES = {
        "When, in disgrace with fortune and men's eyes,",
        "I all alone beweep my outcast state."
    };
    
    public Sonnet29() {    
    }
    
    @Override
    public void recite() {
        for(String s : LINES)
            System.out.println(s);

    }

}
public class PoeticJuggler extends Juggler {
    private Poem poem;
    
    public PoeticJuggler(Poem poem) {
        super();
        this.poem = poem;
    }
    
    public PoeticJuggler(int beanBags, Poem poem) {
        super(beanBags);
        this.poem = poem;
    }
    
    public void perform() {
        super.perform();
        System.out.println("While reciting...");
        poem.recite();
    }
}

PoeticJuggler类的构造器需要传入一个Poem对象引用

现在XML配置文件中将Sonnet29声明为一个bean

<bean id="sonnet29" class="cn.edu.stu.springidol.Sonnet29" />

然后声明一个新的Bean,通过构造器注入对象引用:

<bean id="poeticDuke" class="cn.edu.stu.springidol.PoeticJuggler">
        <constructor-arg value="15" />
        <constructor-arg ref="sonnet29" />
</bean>

运行结果:

通过工厂方法创建Bean:

 有时候静态工厂方法是实例化对象的唯一方法,如单例类

public class Stage {
    private Stage() {
    }
    
    private static class StageSingletonHolder {
        static Stage instance = new Stage();
    }
    
    public static Stage getInstance() {
        return StageSingletonHolder.instance;
    }
}

XML配置方法:

<bean id="theStage" class="cn.edu.stu.springidol.Stage" factory-method="getInstance" />

<factory-method>属性允许调用一个指定的静态方法,从而代替构造方法创建一个类的实例

Bean的作用域:

Spring Bean默认的作用域是singleton,在一个Bean定义只有一个对象实例,如果需要Bean可以被实例化任意次(每次调用创建一个实例),需要使用prototype作用域

<bean id="ticket" class="cn.edu.stu.springidol.Ticket" scope="prototype" />

这样每次调用Bean,返回不同实例

Ticket t1 = (Ticket) ctx.getBean("ticket");
Ticket t2 = (Ticket) ctx.getBean("ticket");
System.out.println(t1 == t2);

结果为false,如果把作用域改成singleton,结果变为true。

Bean的作用域还有request、session、global-session。

初始化和销毁Bean:

当实例化一个Bean时,可能需要执行一些初始化操作确保该Bean处于可用状态,同样,不再需要Bean,将其从容器中移除时,可能还需要按顺序执行一些清除工作。

public class Auditorium {
    public void turnOnLights() {
        System.out.println("Turn on lights");
    }
    
    public void turnOffLights() {
        System.out.println("Turn off lights");
    }
}

当auditorium bean初始化时,需要调用turnOnLights方法,移除时,需要调用turnOffLights方法。

<bean id="auditorium" class="cn.edu.stu.springidol.Auditorium"
        init-method="turnOnLights"
        destroy-method="turnOffLights" />

init-method指定初始化方法,destroy-method指定移除方法

二、注入Bean属性

public interface Instrument {
    void play();
}

public class Saxphone implements Instrument {
    
    @Override
    public void play() {
        System.out.println("TOOT TOOT TOOT");

    }
}

public class Instrumentalist implements Performer {
    public Instrumentalist() {
    }
    
    @Override
    public void perform() {
        System.out.print("Playing " + song + " : ");
        instrument.play();
    }
    
    private String song;
    
    public void setSong(String song) {
        this.song = song;
    }
    
    public String getSong() {
        return song;
    }
    
    private Instrument instrument;
    
    public void setInstrument(Instrument i) {
        instrument = i;
    }

}

XML配置:

<bean id="saxphone" class="cn.edu.stu.springidol.Saxphone" />

<bean id="kenny" class="cn.edu.stu.springidol.Instrumentalist">
        <property name="song" value="Jingle Bells" />
        <property name="instrument" ref="saxphone" />
</bean>

注入内部Bean,kenny还可以这样配置:

<bean id="kenny" class="cn.edu.stu.springidol.Instrumentalist">
        <property name="song" value="Jingle Bells" />
        <property name="instrument"><bean class="cn.edu.stu.springidol.Saxphone" /></property>
</bean>

内部Bean不能被复用,仅适用于一次注入,而且不能被其他Bean引用。

装配集合:

public class OneManBand implements Performer {
    private Collection<Instrument> instruments;
    
    public void setInstruments(Collection<Instrument> instruments) {
        this.instruments = instruments;
    }
    
    @Override
    public void perform() {
        for(Instrument i : instruments)
            i.play();
    }

}
    <bean id="hank" class="cn.edu.stu.springidol.OneManBand">
        <property name="instruments">
            <list>
                <ref bean="saxphone" />
                                <ref bean="..." />
                                <ref bean="..." />
            </list>
        </property>
</bean>            

saxphone必须已经被声明为一个Bean。

原文地址:https://www.cnblogs.com/13jhzeng/p/5733620.html