代码改变世界

spring mvc 学习指南二

2017-03-04 21:57  backyyan  阅读(265)  评论(0编辑  收藏  举报

 Spring控制反转容器的使用

主要介绍Spring如何管理bean和依赖关系。

通过构造器创建一个bean的实例

之前的方法中,可以通过调用ApolicationContext的getBean方法可以获取到一个bean的实例。下面的配置文件中定义了一个名为product的bean。

[html] view plain copy print?
<span style="font-size:14px;"><?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
http://www.springframework.org/schema/tx  
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
http://www.springframework.org/schema/context  
http://www.springframework.org/schema/context/spring-context-3.2.xsd  
http://www.springframework.org/schema/mvc  
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
  
      
    <!-- demo2 -->  
    <bean name="product" class="cn.redis.model.Product"></bean>  
      
</beans></span>  

该bean的定义告诉Spring通过无参的构造来初始化product类。如果不存在该构造器(如果类作者重载了构造器,且没有显示声明默认构造器),则Spring将抛出一个异常。

ps:

应采用id或者name属性表示一个bean。为了让Spring创建一个Product实例,应将Bean定义的name值“product”(具体实践也可以是id值)和Product类型作为参数传递给ApplicationContext的getBean方法。

  1. [java] view plain copy print?
    public void test1(){  
            ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"config1.xml"});  
            Product product = context.getBean("Product",Product.class);  
            product.setName("www");  
            System.out.println("product:"+product.getName());  
        }  

     通过工厂方法创建一个bean实例

    除了通过类的构造器方法Spring还同样支持通过调用一个工厂的方法来初始化类。下面的bean定义展示了通过工厂方法来实例化java.uti.Calendar

  2. [html] view plain copy print?
    <bean name = "calendar" class="java.util.Calendar"  
     factory-method="getInstance"/>  

    DestroyMethod的使用

      有时,我们希望在一些类被销毁前能执行一些方法,Spring考虑到了这样的需求,可以在bean定义中配置destroy-method属性,来指定在销毁前要执行的方法。

    下面的例子中,配置Spring通过java.util.concurrent.Executors的静态方法newCachedThreadPool来创建一个java.util.concurrent.ExecutorService实例,并指定了destroy-method属性为shutdown方法。这样,Spring会在销毁ExecutorService实例前调用shutdown方法。

  3. [html] view plain copy print?
    <bean id="executors" class="java.util.concurrent.Executors"  factory-method="newCachedThreadPool"  destroy-method="newCachedThreadPool"/>  

    向构造器传递参数

    spring 支持通过带参数的构造器来初始化类

    proudct类

  4. [java] view plain copy print?
    public class Product implements Serializable {  
      
        private static final long serialVersionUID = 1L;  
      
        private String name;  
        private String description;  
        private float price;  
      
        public Product() {  
        }  
      
          
      
        public Product(String name,String description,float price) {  
    <span style="white-space:pre">        </span>this.name=name;  
    <span style="white-space:pre">        </span>this.description = description;  
    <span style="white-space:pre">        </span>this.price=price;  
    <span style="white-space:pre">    </span>}  
      
      
        public String getName() {  
            return name;  
        }  
      
        public void setName(String name) {  
            this.name = name;  
        }  
      
        public String getDescription() {  
            return description;  
        }  
      
        public void setDescription(String description) {  
            this.description = description;  
        }  
      
        public float getPrice() {  
            return price;  
        }  
      
        public void setPrice(float price) {  
            this.price = price;  
        }  
      
    }  
    
    如下定义展示了如何通过参数名传递参数
    [html] view plain copy print?
    <bean name="featuredProduct" class="cn.redis.model.Product">  
            <constructor-arg name="name" value="Ultimate Olive Oil" />  
            <constructor-arg name="description" value="The purest olive oil on the market" />  
            <constructor-arg name="price" value="9.95" />  
        </bean>  
    这样在创建product实例时,Spring会调用如下构造器。
    [java] view plain copy print?
    public Product(String name,String description,float price) {  
            this.name=name;  
            this.description = description;  
            this.price=price;  
        }  

    除了通过名称传递参数外,Spring还支持通过指数方式传递参数,具体如下:

    [html] view plain copy print?
    <bean name="featuredProduct2" class="cn.redis.model.Product">  
            <constructor-arg index="0" value="Ultimate Olive Oil" />  
            <constructor-arg index="1"  
                value="The purest olive oil on the market" />  
            <constructor-arg index="2" value="9.95" />  
        </bean>  

    Setter 方式依赖注入

    下面以employee类和address类为例,说明setter方式依赖注入。

  5. [java] view plain copy print?
    package cn.redis.model;  
      
    public class Employee {  
        private String firstName;  
        private String lastName;  
        private Address homeAddress;  
      
        public Employee() {  
        }  
      
        public Employee(String firstName, String lastName, Address homeAddress) {  
            super();  
            this.firstName = firstName;  
            this.lastName = lastName;  
            this.homeAddress = homeAddress;  
        }  
      
        public String getFirstName() {  
            return firstName;  
        }  
      
        public void setFirstName(String firstName) {  
            this.firstName = firstName;  
        }  
      
        public String getLastName() {  
            return lastName;  
        }  
      
        public void setLastName(String lastName) {  
            this.lastName = lastName;  
        }  
      
        public Address getHomeAddress() {  
            return homeAddress;  
        }  
      
        public void setHomeAddress(Address homeAddress) {  
            this.homeAddress = homeAddress;  
        }  
      
        @Override  
        public String toString() {  
            return "Employee [firstName=" + firstName + ", lastName=" + lastName  
                    + ", homeAddress=" + homeAddress + "]";  
        }  
      
    }  
    [java] view plain copy print?
    package cn.redis.model;  
      
    public class Address {  
        private String line1;  
        private String city;  
        private String state;  
        private String zipCode;  
        private String country;  
      
        public Address(String line1, String city, String state, String zipCode,  
                String country) {  
            super();  
            this.line1 = line1;  
            this.city = city;  
            this.state = state;  
            this.zipCode = zipCode;  
            this.country = country;  
        }  
      
        // getters and setters onitted  
      
        @Override  
        public String toString() {  
            return "Address [line1=" + line1 + ", city=" + city + ", state="  
                    + state + ", zipCode=" + zipCode + ", country=" + country + "]";  
        }  
      
    }  

    Employee 依赖于Address类,可以通过如下配置来保证每一个Employee实例都能包含Address类

    [html] view plain copy print?
    <bean name="simpleAddress" class="cn.redis.model.Address">  
            <constructor-arg name="line1" value="151 corner" />  
            <constructor-arg name="city" value="Albany" />  
            <constructor-arg name="state" value="NY" />  
            <constructor-arg name="zipCode" value="99999" />  
            <constructor-arg name="country" value="US" />  
        </bean>  
        <bean name="employee" class="cn.redis.model.Employee">  
            <constructor-arg name="firstName" ref="simpleAddress" />  
            <constructor-arg name="lastName" value="Junio" />  
            <constructor-arg name=" homeAddress " value="Moore" />  
        </bean>  

    simpleAddress 对象是Address类的一个实例,其通过构造器方式实例化。employee对象则通过配置property元素来调用setter方法设置值,需要注意的是,homeAddress属性配置是simpleAddress对象的引用。被引用对象的配置定义无须早于引用其对象的定义。本例中,employee1对象可以出现在simpleAdress 对象定义之前。

    构造器方式的依赖注入

    我们还可以将Address对象通过构造器注入,如下所示

    [html] view plain copy print?
    <bean name="employee2" class="cn.redis.model.Employee">  
            <constructor-arg name="homeAddress"  ref="simpleAddress"/>  
            <constructor-arg name="firstName"  value="w"/>  
            <constructor-arg name="lastName"  value="qq"/>  
        </bean>  
    [html] view plain copy print?
    <bean name="simpleAddress" class="cn.redis.model.Address">  
            <constructor-arg name="line1" value="151 corner" />  
            <constructor-arg name="city" value="Albany" />  
            <constructor-arg name="state" value="NY" />  
            <constructor-arg name="zipCode" value="99999" />  
            <constructor-arg name="country" value="US" />  
        </bean>