zoukankan      html  css  js  c++  java
  • Spring4笔记4--基于XML的DI(依赖注入)

    基于XML的DI(依赖注入):

      Bean 实例在调用无参构造器创建了空值对象后,就要对 Bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。根据注入方式的不同,常用的有两类:设值注入、构造注入。还有另外一种,实现特定接口注入。由于这种方式采用侵入式编程,污染了代码,所以几乎不用。


      注入分类:

        (1) 设值注入:

          设值注入是指,通过 setXXX() 方法传入被调用者的实例。这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="mySchool" class="com.tongji.di01.School">
     9         <property name="name" value="清华大学"/>
    10     </bean>
    11     <bean id="student" class="com.tongji.di01.Student">
    12         <property name="name" value="张三"/>
    13         <property name="age" value="23"/>
    14         <property name="school" ref="mySchool"/>
    15     </bean>
    16 </beans>

        (2) 构造注入:

          构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="mySchool" class="com.tongji.di02.School">
     9         <property name="name" value="清华大学"/>
    10     </bean>
    11     <bean id="student" class="com.tongji.di02.Student">
    12         <constructor-arg name="name" value="李四"/>
    13         <constructor-arg name="age" value="24"/>
    14         <constructor-arg name="school" ref="mySchool"/>
    15         
    16         <!--<constructor-arg index="0" value="李四"/>
    17         <constructor-arg index="1" value="24"/>
    18         <constructor-arg index="2" ref="mySchool"/>
    19         -->
    20         
    21         <!--<constructor-arg value="李四"/>
    22         <constructor-arg value="24"/>
    23         <constructor-arg ref="mySchool"/>
    24         -->
    25         
    26     </bean>
    27 </beans>

      

      命名空间注入:

        对于设值注入与构造注入,在配置文件中,除了使用<property/>或<constructor-arg/>标签外,还可使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分为 p 命名空间注入与 c 命名空间注入。
           p 命名空间注入:采用设值注入方式,故需要有相应的 setXXX()
           c 命名空间注入:采用构造注入方式,故需要有相应的构造器

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:p="http://www.springframework.org/schema/p"
     5     xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans  
     7         http://www.springframework.org/schema/beans/spring-beans.xsd">
     8     
     9     <bean id="mySchool" class="com.tongji.di03.School" p:name="北京大学"/>
    10     
    11     <bean id="student" class="com.tongji.di03.Student" p:name="王五" p:age="25" p:school-ref="mySchool"/>
    12     
    13 </beans> 
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:c="http://www.springframework.org/schema/c"
     5     xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans  
     7         http://www.springframework.org/schema/beans/spring-beans.xsd">
     8     
     9     <bean id="mySchool" class="com.tongji.di04.School">
    10         <property name="name" value="清华大学"/>
    11     </bean>
    12     <bean id="student" class="com.tongji.di04.Student" c:name="赵六" c:age="26" c:school-ref="mySchool"/>
    13 
    14 </beans>

        注意添加的约束:xmlns:p="http://www.springframework.org/schema/p" 和 xmlns:c="http://www.springframework.org/schema/c"

     

      集合属性的注入:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="mySchool1" class="com.tongji.di05.School">
     9         <property name="name" value="清华大学"/>
    10     </bean>
    11     <bean id="mySchool2" class="com.tongji.di05.School">
    12         <property name="name" value="北京大学"/>
    13     </bean>
    14 
    15     <bean id="some" class="com.tongji.di05.Some">
    16         <property name="names">
    17             <array>
    18                 <value>张三</value>
    19                 <value>赵四</value>
    20                 <value>王五</value>
    21             </array>
    22         </property>
    23         <property name="schools">
    24             <list>
    25                 <ref bean="mySchool1"/>
    26                 <ref bean="mySchool2"/>
    27             </list>
    28         </property>
    29         <property name="mySets">
    30             <set>
    31                 <value>中国</value>
    32                 <value>上海</value>
    33                 <value>黄渡理工大学</value>
    34             </set>
    35         </property>
    36         <property name="myMap">
    37             <map>
    38                 <entry key="QQ" value="7654321"/>
    39                 <entry key="Email" value="7654321@qq.com"/>
    40             </map>
    41         </property>
    42         <property name="myProes">
    43             <props>
    44                 <prop key="address">上海曹安公路</prop>
    45                 <prop key="phone">123456778</prop>
    46             </props>
    47         </property>
    48     </bean>
    49 </beans>

      对域属性的自动注入:

        对于域属性的注入,也可不在配置文件中显示的注入。可以通过为<bean/>标签设置autowire 属性值,为域属性进行隐式自动注入。根据自动注入判断标准的不同,可以分为两种:
           byName:根据名称自动注入
           byType:根据类型自动注入
        byName:当配置文件中被调用者 Bean 的 id 值与代码中调用者 Bean 类的属性名相同时,可使用byName 方式,让容器自动将被调用者 Bean 注入给调用者 Bean。容器是通过调用者的 Bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="school" class="com.tongji.di06.School">
     9         <property name="name" value="清华大学"/>
    10     </bean>
    11     
    12     <!-- byName方式域属性自动注入,要求自动注入的bean的id与被注入的属性名相同 -->
    13     <bean id="student" class="com.tongji.di06.Student" autowire="byName">
    14         <property name="name" value="张三"/>
    15         <property name="age" value="23"/>
    16     </bean>
    17 </beans>

        byType:使用 byType 方式自动注入,要求:配置文件中被调用者 bean 的 class 属性指定的类,要与代码中调用者 Bean 类的某域属性类型同源。即要么相同,要么有 is-a 关系(子类,或是实现类)。但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="mySchool" class="com.tongji.di07.School">
     9         <property name="name" value="清华大学"/>
    10     </bean>
    11     
    12     <!-- byType方式域属性自动注入,要求容器中与被注入属性类型具有is-a关系的Bean,只能有一个 -->
    13     <bean id="student" class="com.tongji.di07.Student" autowire="byType">
    14         <property name="name" value="张三"/>
    15         <property name="age" value="23"/>
    16     </bean>
    17 </beans>

      

      使用SPEL表达式注入:(需要进一步学习SPEL表达式)

        SPEL,Spring Expression Language,即 Spring EL 表达式语言。即,在 Spring 配置文件中为 Bean 的属性注入值时,可直接使用 SPEL 表达式计算的结果。SPEL 表达式以#开头,后跟一对大括号。用法:  <bean  id=“abc”   value=“#{…}”/>。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <bean id="person" class="com.tongji.di08.Person">
     9         <property name="pname" value="李四"/>
    10         <property name="page" value="#{T(java.lang.Math).random() * 80}"/>
    11     </bean>
    12     
    13     <bean id="student" class="com.tongji.di08.Student">
    14         <property name="name" value="#{person.pname}"/>
    15         <property name="age" value="#{person.computeAge()}"/>
    16     </bean>
    17 </beans>

      

      使用内部 Bean 注入 :
        若不希望代码直接访问某个 bean,即,在代码中通过 getBean 方法获取该 Bean 实例, 则可将该 Bean 的定义放入调用者 bean 定义的内部

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7 
     8     <!-- 
     9     <bean id="mySchool" class="com.tongji.di09.School">
    10         <property name="name" value="清华大学"/>
    11     </bean>
    12      -->
    13     
    14     <bean id="student" class="com.tongji.di09.Student">
    15         <property name="name" value="张三"/>
    16         <property name="age" value="23"/>
    17         <property name="school">
    18             <bean class="com.tongji.di09.School">
    19                 <property name="name" value="清华大学"/>
    20             </bean>
    21         </property>
    22     </bean>
    23 </beans>

      使用同类抽象 Bean 注入:
        当若干 Bean 实例同属于一个类,且这些实例的属性值又有相同值时,可以使用抽象Bean,以简化配置文件。
        抽象 Bean 是用于让其它 bean 继承的。这个 bean 在 Bean 类中是不能通过 getBean 方法获取的。设置 abstract 属性为 true 来指明该 bean 为抽象 bean,默认值为 false。不过,该 bean 不为抽象 bean 时,也可被继承。只不过,在应用中,用于被继承的 bean 一般为抽象 bean。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <!-- 同类抽象Bean -->
     9     <bean id="baseStudent" class="com.tongji.di10.Student" abstract="true">
    10         <property name="school" value="清华大学"/>
    11         <property name="department" value="计算机学院"/>
    12     </bean>
    13     
    14     <bean id="student1" parent="baseStudent">
    15         <property name="name" value="张三"/>
    16         <property name="age" value="23"/>
    17     </bean>
    18     <bean id="student2" parent="baseStudent">
    19         <property name="name" value="李四"/>
    20         <property name="age" value="24"/>
    21     </bean>
    22     <bean id="student3" parent="baseStudent">
    23         <property name="name" value="王五"/>
    24         <property name="age" value="25"/>
    25     </bean>
    26 </beans>

      使用异类抽象 Bean 注入:

        当若干不同的类对象具有相同的属性,且其值也相同时,可使用异类抽象 Bean。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <!-- 异类抽象Bean -->
     9     <bean id="Person" abstract="true">
    10         <property name="school" value="清华大学"/>
    11         <property name="department" value="计算机学院"/>
    12     </bean>
    13     
    14     <bean id="student" class="com.tongji.di11.Student" parent="Person">
    15         <property name="name" value="张三"/>
    16         <property name="age" value="23"/>
    17     </bean>
    18     
    19     <bean id="teacher" class="com.tongji.di11.Teacher" parent="Person">
    20         <property name="name" value="李四"/>
    21         <property name="workAge" value="24"/>
    22     </bean>
    23 </beans>

      为应用指定多个 Spring 配置文件:

        在实际应用里,随着应用规模的增加,系统中 Bean 数量也大量增加,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将 Spring 配置文件分解成多个配置文件。

        (1) 以配置文件数组方式实现:将所有配置文件的路径定义为一个 String 数组,并将其作为容器初始化参数出现。其将与可变参的容器构造器匹配。

     1 package com.tongji.di12;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class MyTest {
     8     
     9     @Test
    10     public void test01() {
    11         //创建容器
    12         String resource1 = "com/tongji/di12/spring-base.xml";
    13         String resource2 = "com/tongji/di12/spring-beans.xml";
    14 
    15         String[] resources = {resource1, resource2};
    16         @SuppressWarnings("resource")
    17         ApplicationContext ac = new ClassPathXmlApplicationContext(resources);
    18         
    19         Student student = (Student) ac.getBean("student");
    20         System.out.println(student);
    21         
    22         Teacher teacher = (Teacher) ac.getBean("teacher");
    23         System.out.println(teacher);
    24     }
    25     
    26 }

        第12、13行的配置文件为并列关系,不分主次。

        (2) 以父子配置文件方式实现 :
          各配置文件中有一个总文件,总配置文件将各其它子文件通过<import/>引入。在 Java代码中只需要使用总配置文件对容器进行初始化即可。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="
     5         http://www.springframework.org/schema/beans  
     6         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7     
     8     <import resource="classpath:com/tongji/di13/spring-base.xml"/>  <!-- 注意classpath -->
     9     <import resource="classpath:com/tongji/di13/spring-beans.xml"/>  <!-- 也可使用通配符*。但,此时要求父配置文件名不能满足*所能匹配的格式,否则将出现循环递归包含 -->
    10     
    11 </beans>
     1 package com.tongji.di13;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class MyTest {
     8     
     9     @Test
    10     public void test01() {
    11         //创建容器
    12         String resource = "com/tongji/di13/applicationContext.xml";
    13 
    14         @SuppressWarnings("resource")
    15         ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
    16         
    17         Student student = (Student) ac.getBean("student");
    18         System.out.println(student);
    19         
    20         Teacher teacher = (Teacher) ac.getBean("teacher");
    21         System.out.println(teacher);
    22     }
    23     
    24 }
  • 相关阅读:
    ASP.NET Core 中的配置
    依赖注入简介
    Authoriztion Code Flow
    建立IdentityServer项目
    OAuth2 OpenID Connect概述
    Asp.Net Core 项目运行部署到发布
    javascript Template tmpl
    webform ajax 异步请求
    hosts 文件
    webform 使用富文本编辑器
  • 原文地址:https://www.cnblogs.com/qjjazry/p/6362600.html
Copyright © 2011-2022 走看看