1、Spring中的Bean

  • Spring的所有组件都被当作bean来管理。所有的对象都处于Spring的管理中。
  • Spring负责管理和维护所有的Bean,用户无需关心Bean的实例化。
  • 开发者使用Spring框架所作的主要是两件事:开发Bean和配置Bean。
  • 对于Spring框架来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”——所谓IoC的本质。
    Spring框架的本质:根据XML配置驱动Java代码。将代码的耦合提升到XML配置中。

2、实例化Bean的方式

1)设值注入:就是通过property元素控制调用setter方法
优点:

  • 与传统开发更接近,依赖关系更直观。
  • 可以延迟注入的时间,并按需注入。不必要实例化所有的依赖Bean。
  • 在有些参数可选的时候,设置注入显示的更灵活。想设置值,就为之配置property元素,否则就不配置。

2)构造注入:就是constructor-arg控制调用有参数的构造器,由构造器来注入被依赖组件。
优点:

  • 可以在构造器中决定依赖关系的注入顺序。
  • 不提供setter方法,可以避免后续代码对原有bean的破坏。
  • 只有组件的创建者可以实现依赖关系,更符合高内聚的原则。
    实际开发中建议以设置注入为主,构造注入为辅。

3)调用工厂类的静态方法

  • 使用静态工厂方法创建Bean实例时,class指定创建Bean实例的静态工厂方类。
  • Spring还需要知道由哪个静态工厂方法来创建Bean实例。使用factory-method属性来指定静态工厂方法名,Spring将调用静态工厂方法,来返回一个Bean实例。
  • 通过为bean元素添加constructor-arg元素来确定静态工厂方法的参数

4)调用实例工厂的实例工厂方法。

  • 实例工厂方法与静态工厂方法只有一点不同:调用静态工厂方法只需使用工厂类即可,调用实例工厂方法则必须使用工厂实例。
  • 配置实例工厂方法与配置静态工厂方法也基本相似,只有一点区别:配置静态工厂方法指定静态工厂类,配置实例工厂方法则指定工厂实例。

3、案例

题目一: 人借助工具砍柴,砍柴的工具只有斧子
题目二: 人借助工具砍柴,砍柴的工具多了,除了斧子还有锯子,电动工具。

1)设值注入实现题目一

  • 创建两个接口
public interface Person {
    //定义使用工具的方法
    public void useTool();
}
public interface Tool {
    //定义砍柴的工具只有斧子
    public String Axe();
}
  • 创建两个实现类
    其中人的实现类实现了setter方法
public class Lsj implements Person {
    private Tool tool;

    public void setTool(Tool tool) {
        this.tool = tool;
    }

    @Override
    public void useTool() {
        System.out.println("lsj,借助工具砍柴");
        System.out.println(tool.Axe());
    }
}
public class UseAxe implements Tool {

    @Override
    public String Axe() {
        return "砍柴的工具只有斧子";
    }
}
  • 配置Bean文件
<?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.xsd">
    <bean id="Lsj" class="com.no2.t1_1.domain.Lsj" >
        <property name="tool" ref="useAxe"></property>
    </bean>
    <bean id="useAxe" class="com.no2.t1_1.domain.UseAxe"></bean>
</beans>
  • 测试类
public class TestBean {
    public static void main(String[] args){
        ApplicationContext ctx=new ClassPathXmlApplicationContext("com/no2/t1_1/Beans.xml");
        Person p = ctx.getBean("Lsj", Person.class);
        p.useTool();
    }
}

2)构造注入实现题目一

构造注入实现不同的在于person的实现类改用构造方法,以及Bean的配置文件。

  • person实现类
public class Long implements Person {
    private Tool tool;
    //构造注入的构造函数
    public Long(Tool tool){
        this.tool=tool;
    }

    @Override
    public void useTool() {
        System.out.print("long,借助工具砍柴,");
        System.out.println(tool.Axe());
    }
}
  • 配置文件
<?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.xsd">
    <bean id="long" class="com.no2.t1_2.domain.Long">
        <constructor-arg ref="tool"/>
    </bean>
    <bean id="tool" class="com.no2.t1_2.domain.UseAxe"></bean>
</beans>

3)静态工厂方法 实现题目二

题目二这里只创建了一个工具接口

public interface Tool {
    //定义
    public void useTool();
}

然后实现三种工具的实现类

public class Axe implements Tool {
    private String mes;
    public void setMes(String mes){
        this.mes=mes;
    }
    @Override
    public void useTool() {
        System.out.print("long,借助工具砍柴,");
        System.out.println("砍柴的工具多了,你借助的工具是"+mes);
}
}
public class Electric implements Tool {
    private String mes;

    public void setMes(String mes) {
        this.mes = mes;
    }

    @Override
    public void useTool() {
        System.out.print("long,借助工具砍柴,");
        System.out.println("砍柴的工具多了,你借助的工具是"+mes);
    }
}
public class Saw implements Tool {
    private String mes;

    public void setMes(String mes) {
        this.mes = mes;
    }

    @Override
    public void useTool() {
        System.out.print("long,借助工具砍柴,");
        System.out.println("砍柴的工具多了,你借助的工具是"+mes);
    }
}

最重要的是创建静态的工厂类

public class ToolFactory {
    //返回工具实例的静态工厂方法
    public static Tool getTool(String t){
        if (t.equalsIgnoreCase("Axe")){
            return new Axe();
        }else if (t.equalsIgnoreCase("Saw")){
            return new Saw();
        }else{
            return new Electric();
        }
    }
}

配置文件

<?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.xsd">
    <!-- 配置工厂bean,该bean负责产生其他bean实例 -->
    <bean id="Axe" class="com.no2.t1_3.factory.ToolFactory" factory-method="getTool">
        <!-- 配置静态工厂的参数-->
        <constructor-arg value="Axe"></constructor-arg>
        <!-- 驱动Spring以value值为参数来执行Axe的set()方法 -->
        <property name="mes" value="斧子"></property>
    </bean>
    <bean id="Saw" class="com.no2.t1_3.factory.ToolFactory" factory-method="getTool">
        <!-- 配置静态工厂的参数-->
        <constructor-arg value="Saw"></constructor-arg>
        <!-- 驱动Spring以value值为参数来执行Axe的set()方法 -->
        <property name="mes" value="锯子"></property>
    </bean>
    <bean id="Electric" class="com.no2.t1_3.factory.ToolFactory" factory-method="getTool">
        <!-- 配置静态工厂的参数-->
        <constructor-arg value="Electric"></constructor-arg>
        <!-- 驱动Spring以value值为参数来执行Axe的set()方法 -->
        <property name="mes" value="电动工具"></property>
    </bean>
</beans>

4)实例工厂注入实现题目二

跟静态工厂方法不同的是工厂方法不再是静态的。

public class ToolFactory {
    //获得Tool实例的实例工厂方法
    public Tool getTool(String tool){
        if (tool.equalsIgnoreCase("Axe")){
            return new Axe();
        }else if(tool.equalsIgnoreCase("Saw")){
            return new Saw();
        }else{
            return new Electric();
        }
    }
}

以及修改配置文件

<?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.xsd">
    <!-- 配置工厂bean,该bean负责产生其他bean实例 -->
    <bean id="tooFactory" class="com.no2.t1_4.factory.ToolFactory"></bean>
    <bean id="Axe" factory-bean="tooFactory" factory-method="getTool">
        <!-- 配置实例工厂方法的参数 -->
        <constructor-arg value="Axe"></constructor-arg>

    </bean>
    <bean id="Saw" factory-bean="tooFactory" factory-method="getTool">
        <constructor-arg value="Saw"></constructor-arg>
    </bean>
    <bean id="Electric" factory-bean="tooFactory" factory-method="getTool">
        <constructor-arg value="Electric"></constructor-arg>
    </bean>
</beans>