Spring IOC-3

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Carrots_vegetables/article/details/81280809

今天我们继续来学习IOC的两个知识点。

1.IOC通过工厂方法创建对象

2.IOC自动装载(autowire)

代码:

IOC通过工厂方法创建对象

我们之前说过IOC是典型的工厂模式,今天我们就来学习如何使用工厂模式来创建bean。

IOC通过工厂模式创建bean有两种方式:

1.静态工厂方法

2.实例工厂方法

按照惯例,我们还是通过代码来带大家去学习工厂方法。

首先来学习静态工厂方法。

1.创建Car实体类

public class Car {
    private int num;
    private String brand;
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Car(int num, String brand) {
        super();
        this.num = num;
        this.brand = brand;
    }
    public Car() {
        super();
    }
    @Override
    public String toString() {
        return "Car [num=" + num + ", brand=" + brand + "]";
    }
}

2.创建静态工厂类,静态工厂方法。

public class StaticCarFactory {
    private static Map<Integer,Car> cars;
    static{
        cars = new HashMap<Integer,Car>();
        cars.put(1, new Car(1,"奥迪"));
        cars.put(2, new Car(2,"奥拓"));
    }
    public static Car getCar(int num){
        return cars.get(id);
    }
}

3.在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.xsd">

    <!-- 配置静态工厂创建car对象 -->
    <bean id="car1" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="1"></constructor-arg>
    </bean>

</beans>

factory-method指向静态方法。

constructor-arg 的value属性为调用静态方法所传的参数。

4.在测试类中直接获取car1对象。

public class Test {
    public static void main(String[] args) throws SQLException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Car car = (Car) applicationContext.getBean("car1");
        System.out.println(car);
    }
}

这里写图片描述
2.实例工厂方法

1.创建实例工厂类,工厂方法 。

public class InstanceCarFactory {
    private Map<Integer,Car> cars;
    public InstanceCarFactory() {
        cars = new HashMap<Integer,Car>();
        cars.put(1, new Car(1,"奥迪"));
        cars.put(2, new Car(2,"奥拓"));
    }
    public Car getCar(int num){
        return cars.get(num);
    }
}

2.spring.xml中配置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="carFactory" class="com.southwind.entity.InstanceCarFactory"></bean>

    <!-- 通过实例工厂对象创建car对象 -->
    <bean id="car2" factory-bean="carFactory" factory-method="getCar">
        <constructor-arg value="2"></constructor-arg>
    </bean> 

</beans>

3.在测试类中直接获取car2对象。

public class Test {
    public static void main(String[] args) throws SQLException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Car car2 = (Car) applicationContext.getBean("car2");
        System.out.println(car2);
    }
}

这里写图片描述

对比两种方式的区别,静态工厂方法的方式创建car对象,不需要实例化工厂对象,因为静态工厂的静态方法,不需要创建对象即可调用。所以spring.xml只需要配置一个Car bean,而不需要配置工厂bean。

实例工厂方法创建car对象,必须先实例化工厂对象,因为调用的是非静态方法,必须通过对象调用,不能直接通过类来调用,所以spring.xml中需要先配置工厂bean,再配置Car bean。

其实这里考察的就是静态方法和非静态方法的调用。

IOC自动装载(autowire)

我们通过前面的学习,掌握了IOC创建对象的方式,以及DI完成依赖注入的方式,通过配置property的ref属性,可将bean进行依赖注入。

同时Spring还提供了另外一种更加简便的方式:自动装载,不需要手动配置property,IOC容器会自动选择bean完成依赖注入。

自动装载有两种方式:

byName:通过属性名自动装载

byType:通过属性对应的数据类型自动装载

通过代码来看。

1.创建Person实体类。

public class Person {
    private int id;
    private String name;
    private Car car;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Car getCar() {
        return car;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    @Override
    public String toString() {
        return "Person [color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;white-space: inherit !important;">", name=" + name + ", car=" + car + "]";
    }

}

2.spring.xml中配置Car bean和Person bean,并通过自动装载进行依赖注入。

创建person对象时,没有在property中配置car属性,所以IOC容器会自动进行装载,autowire=”byName”表示通过匹配属性名的方式去装载对应的bean,Person实体类中有car属性,所以就将的bean注入到person中。

注意:通过property标签手动进行car的注入优先级更高,若两种方式同时配置,以property的配置为准。

<?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="person" class="com.southwind.entity.Person" autowire="byName"> 
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>

    <bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="2"></constructor-arg>
    </bean>

</beans>

3.测试类中获取person对象。

public class Test {
    public static void main(String[] args) throws SQLException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }
}

这里写图片描述

同理,byType即通过属性的数据类型来配置。

1.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.xsd">

    <bean id="person" class="com.southwind.entity.Person" autowire="byType"> 
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>

    <bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="1"></constructor-arg>
    </bean>

    <bean id="car2" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="2"></constructor-arg>
    </bean>
</beans>

2.测试类中获取person对象。

public class Test {
    public static void main(String[] args) throws SQLException {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }
}

这里写图片描述

会看到控制台直接打印错误信息,这是因为使用了byType进行自动装载,但是spring.xml中配置了两个Car bean,所以IOC容器不知道应该将哪一个bean装载到person对象中,所以报错。使用byType进行自动装载时,spring.xml中只能配置一个装载的bean。

3.现修改spring.xml配置,只保留一个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="person" class="com.southwind.entity.Person" autowire="byType"> 
        <property name="id" value="1"></property>
        <property name="name" value="张三"></property>
    </bean>

    <bean id="car" class="com.southwind.entity.StaticCarFactory" factory-method="getCar">
        <constructor-arg value="1"></constructor-arg>
    </bean>

</beans>

4.测试类中获取person对象。

这里写图片描述

成功。

猜你喜欢

转载自blog.csdn.net/Carrots_vegetables/article/details/81280809
今日推荐