zoukankan      html  css  js  c++  java
  • 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]
        }
    }
  • 相关阅读:
    类加载器
    java类的主动使用方式
    Java类装载器和命名空间
    cas改造
    所有jar文件列出工具
    源码阅读工具_解析所有类的使用情况
    web(s,哈哈,w,没有,d,用处,f)web框架引用类的次数
    struts2类型转换器StrutsTypeConverter的使用
    struts2的验证框架的使用和扩展
    Python3连接MySQL
  • 原文地址:https://www.cnblogs.com/l-y-h/p/11299743.html
Copyright © 2011-2022 走看看