深入浅出Spring IOC-3

今天我们继续来学习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 [id=" + id + ", name=" + name + ", car=" + car + "]";
   }

}


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

创建person对象时,没有在property中配置car属性,所以IOC容器会自动进行装载,autowire="byName"表示通过匹配属性名的方式去装载对应的bean,Person实体类中有car属性,所以就将id="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对象。



成功。


源码:


链接: https://pan.baidu.com/s/1dGDryG5 

密码: k4wd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值