1. 程式人生 > >Spring入門第三課

Spring入門第三課

const 屬性 反射 www hierarchy source nco rep setname

屬性註入

屬性註入就是通過setter方法註入Bean的屬性值或依賴的對象。

屬性植入使用<property>元素,使用name屬性指定Bean的屬性名稱,value屬性或者<value>子節點指定屬性值

屬性註入是實際應用中最常用的註入方式。

構造方法註入

通過構造方法註入Bean的屬性值或依賴的對象,它保證了Bean實例化以後就可以使用。

構造器註入在<constructor-arg>元素裏申明屬性,<constructor-arg>中沒有name屬性

package logan.spring.study;

public class Car {
    
private String brand; private String corp; private int price; private int maxspeed; public Car(String brand, String corp, int price) { super(); this.brand = brand; this.corp = corp; this.price = price; } @Override public String toString() {
return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxspeed=" + maxspeed + "]"; } }
package logan.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public
static void main(String[] args) { // TODO Auto-generated method stub //1.創建Spring的IOC容器對象 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); //2.從 IOC容器中獲取Bean實例 HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello"); //HelloWorld hello = ctx.getBean(HelloWorld.class); //3.調用hello方法 //System.out.println(hello); Car car = ctx.getBean(Car.class); System.out.println(car); } }
<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi"></constructor-arg>
        <constructor-arg value="Shanghai"></constructor-arg>
        <constructor-arg value="3000000"></constructor-arg>
    </bean>

</beans>

還可以這樣配置

<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2"></constructor-arg>
    </bean>

</beans>

當如下配置時,會不合邏輯

<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma"></constructor-arg>
        <constructor-arg value="Shanghai"></constructor-arg>
        <constructor-arg value="240"></constructor-arg>
    </bean>

</beans>
package logan.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.創建Spring的IOC容器對象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.從 IOC容器中獲取Bean實例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
        //HelloWorld hello = ctx.getBean(HelloWorld.class);
        //3.調用hello方法
        //System.out.println(hello);
        
        Car car = (Car) ctx.getBean("car");
        System.out.println(car);
        Car car2 = (Car) ctx.getBean("car2");
        System.out.println(car2);

    }

}

這個是得到的結果

五月 18, 2017 10:00:14 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContex[email protected]: startup date [Thu May 18 22:00:14 CST 2017]; root of context hierarchy
五月 18, 2017 10:00:14 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld‘s Constructor...
HelloWorld‘s Constructor...
Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]
Car [brand=Baoma, corp=Shanghai, price=240.0, maxspeed=0]

可以看到240沒有賦值到maxSpeed上。

如下修改配置文件可以正確賦值

<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg value="Shanghai" type="java.lang.String"></constructor-arg>
        <constructor-arg value="240" type="int"></constructor-arg>
    </bean>

</beans>

得到如下結果:使用構造器註入屬性值時可以指定參數的位置和參數的類型!以區分重載的構造器

五月 18, 2017 10:04:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContex[email protected]: startup date [Thu May 18 22:04:26 CST 2017]; root of context hierarchy
五月 18, 2017 10:04:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld‘s Constructor...
HelloWorld‘s Constructor...
Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]
Car [brand=Baoma, corp=Shanghai, price=0.0, maxspeed=240]

還可以如下配置,使用子節點給屬性賦值

<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg value="Shanghai" type="java.lang.String"></constructor-arg>
        <constructor-arg type="int">
            <value>250</value>
        </constructor-arg>
    </bean>

</beans>

字面值:可以使用字符串表示的值,可以通過<value>元素標簽或者value屬性進行註入。

基本數據類型及其封裝類,String等類型都可以采取字面值註入的方式

若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起來。

<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg type="java.lang.String">
            <value><![CDATA[<Shanghai>]]></value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>250</value>
        </constructor-arg>
    </bean>

</beans>

下面看Bean相互引用

組成應用程序的Bean經常需要相互協作以完成應用程序的功能。要使Bean能夠相互訪問,就必須在Bean配置文件中指定對Bean的引用。

在Bean的配置文件中,可以通過<ref>元素或者ref屬性為Bean的屬性或者構造器參數指定對Bean的引用。

也可以在屬性或者構造器裏包含Bean的聲明,這樣的Bean稱為內部Bean。

package logan.spring.study;

public class Person {
    
    private String name;
    
    private int age;
    
    private Car car;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }
}
<?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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg type="java.lang.String">
            <value><![CDATA[<Shanghai>]]></value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>250</value>
        </constructor-arg>
    </bean>
    
    <bean id="person" class="logan.spring.study.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car" ref="car2"></property>
    </bean>

</beans>
package logan.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.創建Spring的IOC容器對象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.從 IOC容器中獲取Bean實例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
        //HelloWorld hello = ctx.getBean(HelloWorld.class);
        //3.調用hello方法
        //System.out.println(hello);
        
        Car car = (Car) ctx.getBean("car");
        System.out.println(car);
        Car car2 = (Car) ctx.getBean("car2");
        System.out.println(car2);
        Person person = ctx.getBean(Person.class);
        System.out.println(person);
    }

}

下面是輸出結果

五月 18, 2017 10:21:47 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContex[email protected]: startup date [Thu May 18 22:21:47 CST 2017]; root of context hierarchy
五月 18, 2017 10:21:47 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld‘s Constructor...
HelloWorld‘s Constructor...
Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]
Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250]
Person [name=Tom, age=24, car=Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250]]

看內部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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg type="java.lang.String">
            <value><![CDATA[<Shanghai>]]></value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>250</value>
        </constructor-arg>
    </bean>
    
    <bean id="person" class="logan.spring.study.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car">
            <bean class="logan.spring.study.Car">
                <constructor-arg value="Ford"></constructor-arg>
                <constructor-arg value="Changan"></constructor-arg>
                <constructor-arg value="20000000" type="double"></constructor-arg>
            </bean>
        </property>
    </bean>

</beans>

運行結果

五月 18, 2017 10:36:26 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContex[email protected]: startup date [Thu May 18 22:36:26 CST 2017]; root of context hierarchy
五月 18, 2017 10:36:26 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld‘s Constructor...
HelloWorld‘s Constructor...
Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]
Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250]
Person [name=Tom, age=24, car=Car [brand=Ford, corp=Changan, price=2.0E7, maxspeed=0]]

註意:內部Bean不能被外部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
    class:bean的全類名,通過反射的方式在IOC容器中創建bean,所以要求Bean中必須有無參的構造函數
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>
    
    <!-- 通過構造方法來配置Bean的屬性 -->
    <bean id="car" class="logan.spring.study.Car">
        <constructor-arg value="Audi" index="0"></constructor-arg>
        <constructor-arg value="Shanghai" index="1"></constructor-arg>
        <constructor-arg value="3000000" index="2" type="double"></constructor-arg>
    </bean>
    <bean id="car2" class="logan.spring.study.Car">
        <constructor-arg value="Baoma" type="java.lang.String"></constructor-arg>
        <constructor-arg type="java.lang.String">
            <value><![CDATA[<Shanghai>]]></value>
        </constructor-arg>
        <constructor-arg type="int">
            <value>250</value>
        </constructor-arg>
    </bean>
    
    <bean id="person" class="logan.spring.study.Person">
        <property name="name" value="Tom"></property>
        <property name="age" value="24"></property>
        <property name="car">
            <bean class="logan.spring.study.Car">
                <constructor-arg value="Ford"></constructor-arg>
                <constructor-arg value="Changan"></constructor-arg>
                <constructor-arg value="20000000" type="double"></constructor-arg>
            </bean>
        </property>
    </bean>
    
    <bean id="person2" class="logan.spring.study.Person">
        <constructor-arg value="Jerry"></constructor-arg>
        <constructor-arg value="25"></constructor-arg>
        <constructor-arg ref="car"></constructor-arg>
    </bean>

</beans>
package logan.spring.study;

public class Person {
    
    private String name;
    
    private int age;
    
    private Car car;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
    }
    
    public Person() {
        // TODO Auto-generated constructor stub
    }

    public Person(String name, int age, Car car) {
        super();
        this.name = name;
        this.age = age;
        this.car = car;
    }
    
    
}
package logan.spring.study;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.創建Spring的IOC容器對象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.從 IOC容器中獲取Bean實例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
        //HelloWorld hello = ctx.getBean(HelloWorld.class);
        //3.調用hello方法
        //System.out.println(hello);
        
        Car car = (Car) ctx.getBean("car");
        System.out.println(car);
        Car car2 = (Car) ctx.getBean("car2");
        System.out.println(car2);
        Person person = (Person) ctx.getBean("person2");
        System.out.println(person);
        

    }

}

輸出結果如下:

五月 18, 2017 10:43:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContex[email protected]: startup date [Thu May 18 22:43:51 CST 2017]; root of context hierarchy
五月 18, 2017 10:43:51 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld‘s Constructor...
HelloWorld‘s Constructor...
Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]
Car [brand=Baoma, corp=<Shanghai>, price=0.0, maxspeed=250]
Person [name=Jerry, age=25, car=Car [brand=Audi, corp=Shanghai, price=3000000.0, maxspeed=0]]

Spring入門第三課