累成一条狗

Spring入门

一、Spring

1、Spring是什么?

(1)是一个开源框架,用于简化企业级开发。
(2)是一个轻量级的、非侵入性的、一站式的一个容器。
注:
  非侵入性: 基于Spring开发的应用的对象可以不依赖Spring的API。
  一站式: 可以整合其他的框架与第三方类库。
  容器:包含并管理应用对象的生命周期。
(3)核心是IOC、 AOP。
注:
  IOC: 反转控制,或者理解为DI,依赖注入。可以管理各层的组件。
  AOP: 面向切面编程。用来管理事务、日志等。

2、IOC(Inversion of Control)、DI(Dependency Injection)

  IOC,指的是反转控制,即反转资源获取的方向。一般情况下,资源查找方式为 组件向容器发送查找请求,容器响应后返回资源。使用反转控制后,容器主动将资源推送给组件,组件在需要的时候选择所需资源即可。
  DI,指的是依赖注入,IOC的另一种表述形式。组件以预先定义好的形式去接收容器的资源注入(比如使用setter方法来接收值)。

3、未使用IOC前,创建实例对象

  未使用IOC时,在需要用到某类的地方直接实例化(new)对象即可。

package com.hello;

class HelloWorld {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + "]";
    }
}

public class Demo {
    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        helloWorld.setName("Tom");
        System.out.println(helloWorld); // 输出HelloWorld [name=Tom]
    }
}

 

4、使用IOC后,创建实例对象

  使用IOC后,利用配置文件通过反射创建对象实例,并通过ApplicationContext获取对象。
注:
  使用IOC功能需要导入Spring几个核心jar包。
(1)Beans : 包含访问配置文件、创建和管理bean以及进行(IOC/DI)操作相关的所有类。
(2)Core:包含Spring框架基本的核心工具类,Spring的其他组件要都要使用到这个包里的类,Core模块是其他组件的基本核心。
(3)Context :Spring的上下文,即IOC容器,通过上下文可以获得容器中的Bean(提供一种框架式的对象访问方式)。 ApplicationContext接口是Context模块的关键。
(4)SpEl : Expression Language模块提供了一个强大的表达式语言用于在运行时查询和操纵对象。
(5)commons-logging:日志jar包,也可选用log4j。
此处,我导入了(可以使用maven配置依赖信息):
  spring-beans-4.3.14.RELEASE.jar
  spring-context-4.3.14.RELEASE.jar
  spring-core-4.3.14.RELEASE.jar
  spring-expression-4.3.14.RELEASE.jar
  commons-logging-1.2.jar
(6)IOC使用步骤:
  step1:导入相关jar包(或者配置相关依赖信息),配置IOC环境。
  step2:编写配置文件,一般命名为 applicationContext.xml,并在内部配置 bean 对象 。
  step3:实例化applicationContext,并通过 getBean() 方法获取bean对象。

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="helloworld" class="com.hello.HelloWorld">
          <property name="name" value="Jarry"></property>
      </bean>
</beans>

【HelloWorld.java,类模板,通过反射生成的类】
package com.hello;

public class HelloWorld {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + "]";
    }
}

【Demo.java,测试类】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        // 创建IOC对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean对象
        HelloWorld helloWorld = (HelloWorld) applicationContext.getBean("helloworld");
        System.out.println(helloWorld); // 输出 HelloWorld [name=Jarry]
    }
}

 

二、Bean对象的配置与使用

1、配置bean对象(常用方式)

在applicationContext.xml中配置 bean 标签,其中标签属性如下:
(1)class:bean的完整类名,通过反射的方式在 IOC 容器中创建一个Bean对象。
(2)id:唯一标识容器中的bean对象。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="helloworld" class="com.hello.HelloWorld">
</bean>

 

2、获取bean对象步骤

(1)创建Spring的IOC容器对象(ApplicationContext)。
注:
  ApplicationContext是一个接口,其有一个子接口ConfigurableApplicationContext,增加了几个方法,比如refresh() 和 close() ,增加了功能,

其常用实现类:
  ClassPathXmlApplicationContext : 从类路径下加载配置文件。
  FileSystemXmlApplicationContext:从文件路径中加载配置文件。


ApplicationContext实例化时,会实例化所有的单例模式创建的bean。

 

(2)从IOC容器对象中获取Bean实例(getBean(id))

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld = (HelloWorld) applicationContext.getBean("helloworld");

HelloWorld helloWorld = applicationContext.getBean("helloworld", HelloWorld.class); // 推荐写法

 

三、信息注入

1、属性注入(最常用,setter注入)

  属性注入指的是通过类的setter方法注入bean的属性值或者依赖的对象。
(1)注入常量值(比如String,int,double等)
  在 <bean> 标签内部,通过<property> 标签注入信息。
  <property>的属性如下:(类的内部必须存在相关setter方法,否则可能会报错)
    name: 用于指定bean对象对应类中的属性名称。
    value:用于指定属性值(常量值,比如String,int等)。
  二者结合,自动匹配com.hello.HelloWorld 类的 setName()方法,并向其中赋值。

<bean id="helloworld" class="com.hello.HelloWorld">
     <property name="name" value="Jarry"></property>
</bean>

【HelloWorld.java】
package com.hello;

public class HelloWorld {
    private String name;

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + "]";
    }
}

(2)注入对象(引用类型变量)
  ref:用于指定bean对象(与配置文件中的bean形成引用关系)。
  与name属性结合,可以注入bean对象(引用类型)。

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="person" class="com.hello.Person">
          <property name="name" value="Tom"></property>
          <property name="age" value="18"></property>
      </bean>
      
      <!-- 使用ref属性,可以绑定 上述配置的bean 对象 -->
      <bean id="helloworld" class="com.hello.HelloWorld">
          <property name="name" value="Jarry"></property>
          <property name="person" ref="person"></property>
      </bean>
</beans>

【HelloWorld.java】
package com.hello;

public class HelloWorld {
    private String name;
    private Person person;

    public HelloWorld() {
    }

    public String getName() {
        return name;
    }

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

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + ", person=" + person + "]";
    }

}

【Person.java】
package com.hello;

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

    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;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

【Demo.java】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloWorld helloWorld = (HelloWorld) applicationContext.getBean("helloworld");
        System.out.println(helloWorld); //输出 HelloWorld [name=Jarry, person=Person [name=Tom, age=18]]
    }
}

注:
  可以使用 <ref>标签来实现 bean 的引用。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<!-- 使用ref标签,可以绑定 上述配置的bean 对象 -->
<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name" value="Jarry"></property>
    <property name="person">
        <ref bean="person"></ref>
    </property>
</bean>

同时可以使用内部 bean,此时内部bean 不能被其他 bean 引用,只用于其外部 bean。

<!-- 使用内部bean, 不能被其他 外部bean 引用, 只用于此外部 bean, id号可省略-->
<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name" value="Jarry"></property>
    <property name="person">
      <bean class="com.hello.Person">
        <property name="name" value="Jom"></property>
        <property name="age" value="18"></property>
      </bean>
    </property>
</bean>

注:
  级联赋值,可以给引用类型变量进行手动赋值。
  级联(cascade)指的是 多个对象之间的映射关系,建立数据之间的级联关系提高管理效率。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<!-- 使用级联赋值,可以给引用类型变量进行赋值-->
<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name" value="Jarry"></property>
    <property name="person" ref="person"></property> <!--此处不能少,先初始化,才能使用级联赋值-->
    <property name="person.name" value="Rick"></property>
    <property name="person.age" value="38"></property>
</bean>

(3)注入集合、数组。
  注入集合。需使用<list> , <set>, <map>等标签,数组使用<list>标签赋值。且在标签内部 可以使用 <ref> 标签引用 bean对象,可以使用内部bean 来创建一个集合元素。使用<value>标签可以注入常量值(比如String,int等类型的数据)。

【HelloWorld.java】
package com.hello;

import java.util.List;

public class HelloWorld {
    private String name;

    private List<Person> personList;

    public HelloWorld() {
    }

    public String getName() {
        return name;
    }

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

    public List<Person> getPersonList() {
        return personList;
    }

    public void setPersonList(List<Person> personList) {
        this.personList = personList;
    }

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + ", personList=" + personList + "]";
    }
}

【applicationContext.xml】
 <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<bean id="person2" class="com.hello.Person">
    <property name="name" value="Tonny"></property>
    <property name="age" value="38"></property>
</bean>

<!-- 给集合赋值,使用<list>, <set> , <map>等标签-->
<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name" value="Jarry"></property>
    <property name="personList">
     <list>
        <!-- 使用 <ref> 标签注入bean -->
        <ref bean="person"></ref>
        <ref bean="person2"></ref>
        <!-- 使用内部bean创建集合元素 -->
        <bean class="com.hello.Person">
            <property name="name" value="Jack"></property>
            <property name="age" value="17"></property>
        </bean>
     </list>
    </property>
</bean>

注:
  对于Map集合的注入,可以使用<map>标签与<entry>标签,其中<entry>是<map>的子标签,内部可以插入常量值(使用 key 与 value 属性插入) 以及 bean对象(使用key-ref 和 value-ref属性)。
  也可以使用<props>与<prop>标签来注入map集合(不能注入bean对象,通常用于peoperties配置文件)。

【HelloWorld.java】
package com.hello;

import java.util.Map;

public class HelloWorld {
    private Map<String, Person> name;
    private Map<String, String> name2;

    public Map<String, Person> getName() {
        return name;
    }

    public void setName(Map<String, Person> name) {
        this.name = name;
    }

    public HelloWorld() {
    }

    public Map<String, String> getName2() {
        return name2;
    }

    public void setName2(Map<String, String> name2) {
        this.name2 = name2;
    }

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + ", name2=" + name2 + "]";
    }

} 

【applicationContext.xml】
<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<bean id="person2" class="com.hello.Person">
    <property name="name" value="Tonny"></property>
    <property name="age" value="38"></property>
</bean>

<!-- 给集合赋值,使用<map>、<props>标签-->
<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name">
        <!-- 使用map标签,可以注入bean对象 -->
        <map>
            <entry key="Jom" value-ref="person"></entry>
            <entry key="Tonny" value-ref="person2"></entry>
        </map>
    </property>
    <property name="name2">
        <!-- 使用 props标签,不能注入bean对象 -->
        <props>
            <prop key="Jom">Jom</prop>
            <prop key="Tonny">Tonny</prop>
        </props>
    </property>
</bean>

注:
  可以通过<util:list>将集合单独抽出来,当成bean对象来使用(其他bean 可以使用 ref来引用)。
  此处由于使用的是<util>,若出错,可以联网试试。

<util:map id="someMap">
     <entry key="1001" value="java"></entry>
     <entry key="1002" value="android"></entry>
 </util:map>
 
 <property name="name2" ref="someMap"></property>

 

(4)spring表达式(SPEL)注入。
  格式:
    #{表达式}
    #{id名.属性名} 或者#{id名.key}
  若为list集合,
    可以采用#{id名[index]}
  注:
    如果是某个实体类的属性,那么该属性必须存在(get属性)的方法。

<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="name2">
        <!-- 使用 props标签,不能注入bean对象 -->
        <props>
            <prop key="Rick">#{person.name}</prop>
            <prop key="Jarry">#{person2.name}</prop>
        </props>
    </property>
</bean>

2、构造方法注入:

  通过构造方法注入Bean 的属性值或者依赖的对象。原理类似于上述属性注入,此处简略一些重复的功能。
在<bean>标签内部,通过<constructor-arg>标签注入信息。
<constructor-arg>属性如下:
  value:用于指定属性值。
  index:用于指定赋值的参数位置。
  type:用于匹配参数的类型。
  三者结合,可以用来区分不同的构造方法。

<bean id="helloworld" class="com.hello.HelloWorld">
     <constructor-arg value="Tom" index="0"></constructor-arg>
     <constructor-arg value="18" index="1" type="int"></constructor-arg>
 </bean>
 
 <!-- 使用index可以指定赋值的参数位置,使用type可以匹配参数的类型,二者结合,可以用来区分不同的构造方法 -->
 <bean id="helloworld2" class="com.hello.HelloWorld">
     <constructor-arg value="Tom" index="0"></constructor-arg>
     <constructor-arg value="10000" index="1" type="double"></constructor-arg>
 </bean>
 
 
【HelloWorld.java】
package com.hello;

public class HelloWorld {
    private String name;
    private int age;
    private double salary;

    public HelloWorld(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public HelloWorld(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "HelloWorld [name=" + name + ", age=" + age + ", salary=" + salary + "]";
    }
}

注:
  对于value值,可以使用<value>标签的形式注入。
  对于包含特殊字符的字符串,需使用<![CDATA[]]>来注入。

<bean id="helloworld2" class="com.hello.HelloWorld">
    <constructor-arg index="0">
             <!-- 注入 <Tom> 字符串 -->
        <value><![CDATA[<Tom>]]></value>
    </constructor-arg>
    <constructor-arg value="10000" index="1" type="double"></constructor-arg>
</bean>

 

注:
  使用构造器也可以注入对象,原理同上述 ref 与 <ref>标签,此处不再赘述。
  使用构造器也可以注入集合,原理同上述 <list>, <map>等标签,此处不再赘述。

3、自动注入(不常用)

  IOC容器可以自动装配bean。上述两种形式中,都是自己手动配置(通过ref来配置bean)。
  若想自动配置,可以使用<bean autowire="">, 其用于指定自动注入规则,其中 autowire 可以使用byType,byName,constructor,简化注入配置。
    byType:根据类型自动匹配。若有两个及以上相同类型的bean,则匹配会出现异常。
    byName:根据名称自动匹配。必须将bean的名称与属性名设置的完全相同,否则匹配不上。
    constructor:通过构造器自动匹配,若存在多个构造器时,配置会很复杂,不推荐使用。

【HelloWorld.java】
package com.hello;

public class HelloWorld {
    private Person person1;
    private Person person2;

    public Person getPerson1() {
        return person1;
    }

    public void setPerson1(Person person1) {
        this.person1 = person1;
    }

    public Person getPerson2() {
        return person2;
    }

    public void setPerson2(Person person2) {
        this.person2 = person2;
    }

    @Override
    public String toString() {
        return "HelloWorld [person1=" + person1 + ", person2=" + person2 + "]";
    }

}

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="person" class="com.hello.Person">
          <property name="name" value="Jom"></property>
          <property name="age" value="18"></property>
      </bean>
      
      <bean id="person2" class="com.hello.Person">
          <property name="name" value="Tonny"></property>
          <property name="age" value="38"></property>
      </bean>
      
      <!-- 根据名字匹配,若未匹配上,则赋值为null-->
      <bean id="helloworld" class="com.hello.HelloWorld" autowire="byName"></bean>
</beans>

此时由于,person不能与helloworld中的person1匹配,所以最后person1为null。
输出:
  HelloWorld [person1=null, person2=Person [name=Tonny, age=38]]

此时若将autowire的值改为 byType,会报错,因为有两个相同类型的bean。
<bean id="helloworld" class="com.hello.HelloWorld" autowire="byType"></bean>

 

4、Bean间的关系(继承、依赖)

(1)继承:
  一个bean的配置可以继承另一个bean的配置,即获取父bean的属性值。
  在<bean>标签中,使用parent属性获取被继承的bean的id即可,可以继承父bean的大部分属性(比如abstract、autowire不会被继承)。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person1" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<!-- 配置bean时,可以继承另一个bean的配置,并添加其他修改 -->
<bean id="person2" parent="person1">
    <property name="age" value="38"></property>
</bean>

<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="person1" ref="person1"></property>
    <property name="person2" ref="person2"></property>
</bean>

一个bean可以定义为抽象bean,使用abstract="true"。此时不能被IOC容器实例化,只能被继承。且此时抽象bean的class可以忽略(此时abstract="true"必须有),由子类实现class。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person1" abstract="true">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<!-- 配置bean时,可以继承另一个bean的配置,并添加其他修改 -->
<bean id="person2" class="com.hello.Person" parent="person1">
    <property name="age" value="38"></property>
</bean>

<bean id="helloworld" class="com.hello.HelloWorld">
    <property name="person1" ref="person1"></property>
    <property name="person2" ref="person2"></property>
</bean>

(2)依赖
  一个bean可以依赖于其他bean(可以为多个)。此时需要被依赖的bean被实例化,才能实例化bean。若被依赖的bean没有被IOC容器实例化,会报错。
  在<bean>标签中使用depends-on来指定被依赖的bean。
  其中 多个bean间使用 “,” 隔开。

<!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
<bean id="person1" class="com.hello.Person">
    <property name="name" value="Jom"></property>
    <property name="age" value="18"></property>
</bean>

<!-- 配置bean时,可以继承另一个bean的配置,并添加其他修改 -->
<bean id="person2" parent="person1">
    <property name="age" value="38"></property>
</bean>

<bean id="helloworld" class="com.hello.HelloWorld" depends-on="person1, person2">
    <property name="person1" ref="person1"></property>
    <property name="person2" ref="person2"></property>
</bean>

 

四、Spring控制Bean对象(创建、销毁、初始化)

1、控制对象的创建方式(即其使用范围)。

  在<bean>标签中由scope属性控制。scope有两个值singleton(默认值)和prototype。
比如:
  <bean scope="singleton" id="s"></bean> //单例模式,该组件在Spring容器中只有一个bean对象。无论getBean("id")多少次,都是同一个对象。
  <bean scope="prototype" id="p"></bean> //原型模式,该组件每次getBean("id")都会返回一个新的对象。

2、指定对象的初始化方法。

  在<bean>标签中由init-method属性控制。
比如:
  <bean init-method="init"></bean>, 其中init可以为任何方法名,但此方法必须存在。则创建对象后会自动调用 public void init(){} 方法,若没有此方法,会报错。

3、指定对象的销毁方法。

  在<bean>标签中由destroy-method属性控制(调用某方法,类似init-method)。

4、控制单例对象的创建时机。

  默认情况下,单例对象在Spring容器创建时同时实例化,并调用初始化方法(init-method属性存在的话)。可以使用<bean>标签的lazy-init="true"属性将创建时机推迟到getBean()方法调用时。

【Person.java】
package com.hello;

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

    public Person() {
        System.out.println("create...");
    }

    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;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }

    public void init() {
        System.out.println("init...");
    }

    public void destory() {
        System.out.println("destory...");
    }
}

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="person" class="com.hello.Person" init-method="init" destroy-method="destory">
          <property name="name" value="Jom"></property>
          <property name="age" value="18"></property>
      </bean>
</beans>

【Demo.java】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person"); // 获取bean对象
        System.out.println(person);
        Person person1 = (Person) applicationContext.getBean("person"); // 获取bean对象
        System.out.println(person1);
        System.out.println(person == person1); // 输出 true , 默认使用单例模式创建,即获取的是同一个bean对象
        applicationContext.close();// 这里已经销毁了bean实例
        Person person2 = (Person) applicationContext.getBean("person"); // 再次创建时,会报错
        System.out.println(person2);
    }
}

 

五、其余配置bean对象的方式

  上述用的都是使用 全类名的方式实现bean对象的配置。还有其余的方式可以配置bean对象。

1、静态工厂方法配置bean

  将对象的创建过程封装到静态方法中,当需要用到某对象时,直接从静态方法中获取。
(1)使用静态方法,并返回一个bean对象。
(2)配置<bean>,其有三个属性,
    id为对象唯一标识号,
    class为bean对象对应的类,
    factory-method为静态方法。
  其中可以使用<constructor-arg>向方法传递参数。

【Person.java】
package com.hello;

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

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public static Person getInstance(String name, int age) {
        return new Person(name, age);
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="person" class="com.hello.Person" factory-method="getInstance">
          <constructor-arg index="0" value="Tom"></constructor-arg>
          <constructor-arg index="1" value="20"></constructor-arg>
      </bean>
</beans>

【Demo.java】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person"); // 获取bean对象
        System.out.println(person);  // 输出 Person [name=Tom, age=20]
    }
}

2、对象工厂方法配置bean

  首先得实例化一个bean对象,再去调用bean对象的实例方法去返回一个bean对象。
(1)使用非静态(实例)方法,并返回一个bean对象。
(2)配置一个<bean>,用于实例化某对象。
(3)再配置一个<bean>,通过 factory-bean 来引用上个<bean>,并使用factory-method来选择方法。

【Person.java】
package com.hello;

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

    public Person() {
        super();
    }

    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Person getInstance(String name, int age) {
        return new Person(name, age);
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="people" class="com.hello.Person"></bean>
      
      <bean id="person" factory-bean="people" factory-method="getInstance">
          <constructor-arg index="0" value="Tom"></constructor-arg>
          <constructor-arg index="1" value="20"></constructor-arg>
      </bean>
</beans>

【Demo.java】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person"); // 获取bean对象
        System.out.println(person);  // 输出 Person [name=Tom, age=20]
    }
}

3、使用FactoryBean的方式配置bean

(1)实现FactoryBean接口,并重写相关方法。
  getObject() 用于返回一个对象。
  isSingleton() 用于判断是否为单例模式。
(2)配置bean对象,其调用 getObject()方法返回bean对象。

【PersonFactory.java】
package com.hello;

import org.springframework.beans.factory.FactoryBean;

public class PersonFactory implements FactoryBean<Person> {

    private String name;
    private int age;

    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;
    }

    /**
     * 返回一个对象
     */
    @Override
    public Person getObject() throws Exception {
        return new Person(name, age);
    }

    @Override
    public Class<Person> getObjectType() {
        return Person.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

【applicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 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/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

      <!-- 配置bean对象,id为bean对象的唯一标识号, class为类路径-->
      <bean id="person" class="com.hello.PersonFactory">
          <property name="name" value="Jarry"></property>
          <property name="age" value="20"></property>
      </bean>
</beans>

【Demo.java】
package com.hello;

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

public class Demo {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person"); // 获取bean对象
        System.out.println(person);  // 输出 Person [name=Jarry, age=20]
    }
}

 

posted on 2019-08-04 21:08  累成一条狗  阅读(732)  评论(0编辑  收藏  举报

导航