zoukankan      html  css  js  c++  java
  • Spring IoC — 基于XML的配置

    1、属性注入

    注意点:
    1)如果类中显示定义了一个带参的构造函数,则一定还要显示提供一个无参构造函数,否则使用属性注入时将抛出异常。
    2)JavaBean关于属性命名的特殊规范。Spring只会检查Bean中是否有对应的Setter方法,至于Bean中是否有对应的属性变量则不做要求。如maxSpeed对应setMaxSpeed(),brand对应setBrand()。
    所以<property>元素的属性变量名应满足:xxx的属性对应setXxx()方法。变量的前两个字母要么全部大写,要么全部小写。
     
    Car类:
    package com.ioc.ch4_3_1;
    /**
     * Created by gao on 16-3-25.
     */
    public class Car {
        private int maxSpeed;
        public String brand;
        private double price;
        public Car() {
        }
        public Car(int maxSpeed, String brand, double price) {
            this.maxSpeed = maxSpeed;
            this.brand = brand;
            this.price = price;
        }
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
        }
        public void setBrand(String brand) {
            this.brand = brand;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public int getMaxSpeed() {
            return maxSpeed;
        }
        public String getBrand() {
            return brand;
        }
        public double getPrice() {
            return price;
        }
        public String toString() {
            return "brand:" + brand + "/maxSpeed:" + maxSpeed + "/price:" + price;
        }
    }

    beans.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="car" class="com.ioc.ch4_3_1.Car">
            <property name="maxSpeed"><value>300</value></property>
            <property name="brand"><value>奥迪</value></property>
            <property name="price"><value>150000.00</value></property>
        </bean>
    </beans>

    测试类:

    package com.ioc.ch4_3_1;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * Created by gao on 16-3-25.
     */
    public class Test {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\ioc\ch4_3_1\beans.xml");
            Car car = (Car) ctx.getBean("car");
            System.out.println(car.toString());
        }
    }
    输出结果:
    brand:奥迪/maxSpeed:300/price:150000.0
     
    2、构造函数注入
    注意点:循环依赖问题。Spring容器能顺利实例化以构造函数注入方式配置的Bean有一个前提是:Bean构造函数入参引用的对象必须已经准备就绪。如果两个Bean都采用构造函数注入,而且都通过构造函数入参引用对方,则会发生循环依赖问题。这时可以将构造函数注入方式调整为属性注入方式。
    Car类:
    package com.ioc.ch4_3_2;
    /**
     * Created by gao on 16-3-25.
     */
    public class Car {
        private int maxSpeed;
        public String brand;
        private double price;
        private String corp;
        public Car() {
        }
        public Car(String brand, double price) {
            this.brand = brand;
            this.price = price;
        }
        public Car(int maxSpeed, String brand, double price) {
            this.maxSpeed = maxSpeed;
            this.brand = brand;
            this.price = price;
        }
        public Car(String brand, String corp, int maxSpeed) {
            this.brand = brand;
            this.corp = corp;
            this.maxSpeed = maxSpeed;
        }
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
        }
        public void setBrand(String brand) {
            this.brand = brand;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public String getCorp() {
            return corp;
        }
        public void setCorp(String corp) {
            this.corp = corp;
        }
        public int getMaxSpeed() {
            return maxSpeed;
        }
        public String getBrand() {
            return brand;
        }
        public double getPrice() {
            return price;
        }
        public String toString() {
            return "brand:" + brand + "	maxSpeed:" + maxSpeed + "	price:" + price + "	corp:" + corp;
        }
    }

    Boss类:

    package com.ioc.ch4_3_2;
    public class Boss {
        private String name;
        private Car car;
        private Office office;
        public Boss(String name, Car car, Office office) {
            this.name = name;
            this.car = car;
            this.office = office;
        }
        public Boss(String name, Car car) {
            this.name = name;
            this.car = car;
        }
        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;
        }
        public String toString(){
            return "name:"+name+"	car:"+car.getBrand()+"	office:"+office;
        }
    }

    Office类:

    package com.ioc.ch4_3_2;
    public class Office {
       
    }

    beans.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">
        <!--构造函数注入:type -->
        <bean id="car1" class="com.ioc.ch4_3_2.Car">
            <constructor-arg type="java.lang.String">
                <value>car1_甲壳虫</value>
            </constructor-arg>
            <constructor-arg type="double">
                <value>300000.0</value>
            </constructor-arg>
        </bean>
        <!--构造函数注入:index-->
        <bean id="car2" class="com.ioc.ch4_3_2.Car">
            <constructor-arg index="0" value="300"/>
            <constructor-arg index="1" value="car2_宝马"/>
            <constructor-arg index="2" value="200000.0"/>
        </bean>
        <!--构造函数注入:type&index -->
        <bean id="car3" class="com.ioc.ch4_3_2.Car">
            <constructor-arg index="0" type="java.lang.String">
                <value>car3_红旗CA72</value>
            </constructor-arg>
            <constructor-arg index="1" type="java.lang.String">
                <value>中国一汽</value>
            </constructor-arg>
            <constructor-arg index="2" type="int">
                <value>200</value>
            </constructor-arg>
        </bean>
        <!--构造函数注入:自动识别入参类型 -->
        <bean id="boss1" class="com.ioc.ch4_3_2.Boss">
            <constructor-arg>
                <value>John</value>
            </constructor-arg>
            <constructor-arg>
                <ref bean="car1" />
            </constructor-arg>
            <constructor-arg>
                <ref bean="office" />
            </constructor-arg>
        </bean>
        <bean id="car" class="com.ioc.ch4_3_2.Car"/>
        <bean id="office" class="com.ioc.ch4_3_2.Office" />
     </beans>

    测试类:

    package com.ioc.ch4_3_2;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * Created by gao on 16-3-25.
     */
    public class Test {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\ioc\ch4_3_2\beans.xml");
            Car car1 = (Car) ctx.getBean("car1");
            System.out.println(car1.toString());
            System.out.println("--------------------------------");
            Car car2 = (Car) ctx.getBean("car2");
            System.out.println(car2.toString());
            System.out.println("--------------------------------");
            Car car3 = (Car) ctx.getBean("car3");
            System.out.println(car3.toString());
            System.out.println("--------------------------------");
            Boss boss1 = (Boss) ctx.getBean("boss1");
            System.out.println(boss1.toString());
        }
    }
    输出结果:
    brand:car1_甲壳虫 maxSpeed:0 price:300000.0 corp:null
    --------------------------------
    brand:car2_宝马 maxSpeed:300 price:200000.0 corp:null
    --------------------------------
    brand:car3_红旗CA72 maxSpeed:200 price:0.0 corp:中国一汽
    --------------------------------
    name:John car:car1_甲壳虫 office:com.ioc.ch4_3_2.Office@9eed10a
     
    3、工厂方法注入
    有非静态工厂方法和静态工厂方法两种方式
    Car类:
    package com.ioc.ch4_3_3;
    /**
     * Created by gao on 16-3-25.
     */
    public class Car {
        private int maxSpeed;
        public String brand;
        private double price;
        public Car() {
        }
        public Car(int maxSpeed, String brand, double price) {
            this.maxSpeed = maxSpeed;
            this.brand = brand;
            this.price = price;
        }
        public void setMaxSpeed(int maxSpeed) {
            this.maxSpeed = maxSpeed;
        }
        public void setBrand(String brand) {
            this.brand = brand;
        }
        public void setPrice(double price) {
            this.price = price;
        }
        public int getMaxSpeed() {
            return maxSpeed;
        }
        public String getBrand() {
            return brand;
        }
        public double getPrice() {
            return price;
        }
        public String toString() {
            return "brand:" + brand + "	maxSpeed:" + maxSpeed + "	price:" + price;
        }
    }

    CarFactory类:

    package com.ioc.ch4_3_3;
    public class CarFactory {
        //创建Car的工厂方法
       public Car createHongQiCar(){
           Car car = new Car();
           car.setBrand("car5_奔驰");
           return car;
       }
       //工厂类方法是静态的
       public static Car createCar(){
           Car car = new Car();
           return car;
       }
    }

    beans.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="carFactory" class="com.ioc.ch4_3_3.CarFactory"/>
        <bean id="car5" factory-bean="carFactory" factory-method="createHongQiCar"/>
        <bean id="car6" class="com.ioc.ch4_3_3.CarFactory" factory-method="createCar"/>
     </beans>

    测试类:

    package com.ioc.ch4_3_3;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    /**
     * Created by gao on 16-3-25.
     */
    public class Test {
        public static void main(String[] args) {
            ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com\ioc\ch4_3_3\beans.xml");
            Car car5 = (Car) ctx.getBean("car5");
            System.out.println(car5.toString());
            System.out.println("-----------------------");
            Car car6 = (Car) ctx.getBean("car6");
            System.out.println(car6.toString());
        }
    }
    输出结果:
    brand:car5_奔驰 maxSpeed:0 price:0.0
    -----------------------
    brand:null maxSpeed:0 price:0.0
    注入方法的考量:
    1)支持使用构造函数注入的理由:
        · 构造函数可以保证一些重要的属性在Bean实例化时就设置好,避免了因为一些重要属性没有提供,导致一个无用Bean实例的情况;
        · 不需要为每个属性提供Setter方法,减少了类的方法个数;    
        · 可以更好地封装类变量,不需要为每个属性指定setter方法,避免外部错误的调用。
    2)更多的开发者更倾向于使用属性注入方式,反对构造函数注入的理由:
        · 如果一个类的属性众多,构造函数的签名将变成一个庞然大物,可读性很差;
        · 灵活性不强,在有些属性是可选的情况下,如果通过构造函数注入,也需要为可选的参数提供一个null值;
        · 如果有多个构造函数,需要考虑配置文件和具体构造函数匹配歧义的问题,配置上相对复杂;
        · 构造函数不利于类的继承和扩展,因为子类需要引用到父类复杂的构造函数;
        · 构造函数注入有时会造成循环依赖的问题。
    3)对于一个全新的应用来说,不推荐使用工厂方法的注入方式。
  • 相关阅读:
    第一节,Django+Xadmin打造上线标准的在线教育平台—创建用户app,在models.py文件生成3张表,用户表、验证码表、轮播图表
    Tensorflow 错误:Unknown command line flag 'f'
    Python 多线程总结
    Git 强制拉取覆盖本地所有文件
    Hive常用函数 傻瓜学习笔记 附完整示例
    Linux 删除指定大小(范围)的文件
    Python 操作 HBase —— Trift Trift2 Happybase 安装使用
    梯度消失 梯度爆炸 梯度偏置 梯度饱和 梯度死亡 文献收藏
    Embedding 文献收藏
    深度学习在CTR预估中的应用 文献收藏
  • 原文地址:https://www.cnblogs.com/yangyquin/p/5320866.html
Copyright © 2011-2022 走看看