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)对于一个全新的应用来说,不推荐使用工厂方法的注入方式。
  • 相关阅读:
    一些名词解释
    less那些事儿
    正则表达式检测汉字
    正则匹配括号中内容
    atom中vue高亮支持emmet语法
    正则匹配标签内内容
    联想一体机u盘启动设置
    vuejs时间格式化
    graphicsmagick常用命令
    js中对象的深度复制
  • 原文地址:https://www.cnblogs.com/yangyquin/p/5320866.html
Copyright © 2011-2022 走看看