zoukankan      html  css  js  c++  java
  • [Js-Spring]基于 XML 的 DI

    注入分类

    (1)设值注入:先调用 Bean 的无参构造函数,然后通过 setter 方法传入被调用者的实例。

    <!-- bean definitions here -->
    <bean id="mySchool" class="com.neu.di01.School">
        <property name="sname" value="neu"></property>
    </bean>
    <bean id="myStudent" class="com.neu.di01.Student">
        <property name="name" value="js"></property>
        <property name="age" value="23"></property>
        <property name="school" ref="mySchool"></property>
    </bean>

    注:对于其他 Bean 对象的引用,除了<bean/>标签的 ref 属性外,还可以使用 <ref/> 标签

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

    <constructor-arg> 标签中用于指定参数的属性:

    name:指定参数名称

    index:指明该参数对应构造器的第几个参数,从0开始,不过该属性可以不需要,但是需要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致

       另外,type属性可用于指定类型,基本类型直接写类型关键字即可,非基本类型需要写全限定性类名

    <!-- bean definitions here -->
    <bean id="mySchool" class="com.neu.di02.School">
        <property name="sname" value="neu"></property>
    </bean>
    <bean id="myStudent" class="com.neu.di02.Student">
        <constructor-arg name="name" value="js"></constructor-arg>
        <constructor-arg name="age" value="22"></constructor-arg>
        <constructor-arg name="school" ref="mySchool"></constructor-arg>
        <!-- 
        <constructor-arg value="js"></constructor-arg>
        <constructor-arg value="22"></constructor-arg>
        <constructor-arg ref="mySchool"></constructor-arg>
         -->
        <!-- 
        <constructor-arg index="0" value="js"></constructor-arg>
        <constructor-arg index="1" value="22"></constructor-arg>
        <constructor-arg index="2" ref="mySchool"></constructor-arg>
         -->
    </bean>

    (3)特定接口注入:采用了侵入式编程,污染了代码,几乎不用

     命名空间注入(了解)

    对于设值注入和构造注入,除了使用 <property/>或<constructor-arg/>标签外,还可以使用命名空间注入的方式,让注入的值以<bean/>标签属性的方式出现。根据注入实现方式的不同,分别以 p 命名空间和 c 命名空间注入。

    p 命名空间注入:采用设值注入,需要相应的 setter 方法

    c 命名空间注入:采用构造注入,需要相应的构造器

    (1)p 命名空间注入

    采用约束

    xmlns:p="http://www.springframework.org/schema/p"
    <!-- bean definitions here -->
    <bean id="mySchool" class="com.neu.di03.School" p:sname="北京大学"></bean>
    <bean id="myStudent" class="com.neu.di03.Student" p:name="张三"
        p:age="22" p:school-ref="mySchool"></bean>

    (2)c 命名空间注入

    采用约束

    xmlns:c="http://www.springframework.org/schema/c"
    <!-- bean definitions here -->
    <bean id="mySchool" class="com.neu.di04.School">
        <property name="sname" value="清华大学"></property>
    </bean>
    <bean id="myStudent" class="com.neu.di04.Student" c:name="张三"
        c:age="22" c:school-ref="mySchool"></bean>

    集合属性注入

     分别为数组,List,Set,Map,Properties注入值,例子如下,

    School.java

    package com.neu.di05;
    
    public class School {
        private String sname;
    
        public void setSname(String sname) {
            this.sname = sname;
        }
    
        @Override
        public String toString() {
            return "School [sname=" + sname + "]";
        }
    }

    Some.java

    package com.neu.di05;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    public class Some {
        private School[] schools;
        private List<String> myList;
        private Set<String> mySet;
        private Map<String, Object> myMap;
        private Properties myPros;
    
        public void setSchools(School[] schools) {
            this.schools = schools;
        }
    
        public void setMyList(List<String> myList) {
            this.myList = myList;
        }
    
        public void setMySet(Set<String> mySet) {
            this.mySet = mySet;
        }
    
        public void setMyMap(Map<String, Object> myMap) {
            this.myMap = myMap;
        }
    
        public void setMyPros(Properties myPros) {
            this.myPros = myPros;
        }
    
        @Override
        public String toString() {
            return "Some [schools=" + Arrays.toString(schools) + ", myList=" + myList + ", mySet=" + mySet + ", myMap="
                    + myMap + ", myPros=" + myPros + "]";
        }
    
    }

    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:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
        <!-- bean definitions here -->
        <bean id="school1" class="com.neu.di05.School">
            <property name="sname" value="清华大学"></property>
        </bean>
        <bean id="school2" class="com.neu.di05.School">
            <property name="sname" value="北京大学"></property>
        </bean>
        <bean id="some" class="com.neu.di05.Some">
            <property name="schools">
                <array>
                    <ref bean="school1" />
                    <ref bean="school2" />
                </array>
            </property>
            <property name="myList">
                <list>
                    <value>张三</value>
                    <value>李四</value>
                </list>
            </property>
            <property name="mySet">
                <set>
                    <value>北京</value>
                    <value>上海</value>
                </set>
            </property>
            <property name="myMap">
                <map>
                    <entry key="QQ" value="123"></entry>
                    <entry key="WeiXin" value="456"></entry>
                </map>
            </property>
            <property name="myPros">
                <props>
                    <prop key="地址">辽宁省沈阳市</prop>
                    <prop key="名称">neu</prop>
                </props>
            </property>
        </bean>
    
    </beans>

    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:c="http://www.springframework.org/schema/c"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    
        <!-- bean definitions here -->
        <bean id="school1" class="com.neu.di06.School">
            <property name="sname" value="清华大学"></property>
        </bean>
        <bean id="school2" class="com.neu.di06.School">
            <property name="sname" value="北京大学"></property>
        </bean>
        <bean id="some" class="com.neu.di06.Some">
            <property name="schools">
                <array>
                    <ref bean="school1" />
                    <ref bean="school2" />
                </array>
            </property>
            <property name="arrays" value="aaa,bbb"></property>
            <property name="myList" value="张三s,李四"></property>
            <property name="mySet" value="北京,上海"></property>
            <property name="myMap">
                <map>
                    <entry key="QQ" value="123"></entry>
                    <entry key="WeiXin" value="456"></entry>
                </map>
            </property>
            <property name="myPros">
                <props>
                    <prop key="地址">辽宁省沈阳市</prop>
                    <prop key="名称">neu</prop>
                </props>
            </property>
        </bean>
    
    </beans>

    MyTest.java

    package com.neu.di05;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
    
        @Test
        public void test01() {
            // 加载Spring配置文件,创建Spring容器对象
            String resource = "com/neu/di05/applicationContext.xml";
            ApplicationContext ac = new ClassPathXmlApplicationContext(resource);
            // 从容器中获取指定的Bean对象
            Some some = (Some) ac.getBean("some");
            System.out.println(some);
            ((ClassPathXmlApplicationContext) ac).close();
        }
    }

    对于域属性的自动注入

    byName 方式自动注入

    配置文件中被调用者的 Bean 的 id 值与代码中调用者 Bean 的属性名相同时,可以使用 byName 的方式,让容器自动将被调用者 Bean 注入给调用者 Bean 。

    如图中 id 为 school 的 Bean,正好对应 Student 类中定义的 school 成员变量,在 id 为 myStudent 的 Bean 中直接定义自动注入方式 autowrite=“byName” 即可

    byType 方式自动注入

    配置文件中被调用者Bean的class属性指定的类,必须要与代码中被调用者Bean类的某域属性同源,即,相同或者具有is-a关系(子类,或者实现类)。同源的被调用者Bean只能有一个,多于一个则会报错,不知道该匹配哪一个。

    使用SPEL表达式

    SPEL(Spring Expression Language),即 Spring EL 表达式语言。即,在 Spring 配置文件中为 Bean 的属性注入值的时候,可以直接使用 SPEL 表达式计算结果。SPEL表达式以#开头,后加一对大括号。

    用法:<bean id="abc" value="#{…}" />。

    Person.java

    package com.neu.di10;
    
    public class Person {
        private String pname;
        private int page;
    
        // getter and setter
    
        // 计算年龄,大于25岁则按照25岁计算
        public int computeAge() {
            return this.page > 25 ? 25 : this.page;
        }
        
        // toString
    
    }

    Student.java

    package com.neu.di10;
    
    public class Student {
        private String name;
        private int age;
    
        // getter and setter
    
        // toString
    
    }

    applicationContext.xml 中的配置

    <bean id="myPerson" class="com.neu.di10.Person">
        <property name="pname" value="wx"></property>
        <property name="page" value="#{T(java.lang.Math).random()*50}"></property>
    </bean>
    <bean id="myStudent" class="com.neu.di10.Student">
        <property name="name" value="#{myPerson.pname}"></property>
        <property name="age" value="#{myPerson.computeAge()}"></property>
    <!-- <property name="age" value="#{myPerson.page>25?25:myPerson.page}"></property> -->
    </bean>

    上面仅仅是个例子,具体详细的所有用法可以查看框架解压包下面的 spring-framework-4.2.1.RELEASEdocsspring-framework-referencehtmlsingleindex.html 中查找 SPEL 用法

    框架包百度云链接 密码是 ycgm

    使用内部 Bean 注入

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

    匿名 Bean(虽然无法在代码中通过 getBean() 方法获取,但是可以通过类型自动注入)

    <!-- 匿名Bean -->
    <bean class="com.neu.di11.School">
        <property name="sname" value="neu"></property>
    </bean>
    <bean id="myStudent" class="com.neu.di11.Student" autowire="byType">
        <property name="name" value="js"></property>
        <property name="age" value="23"></property>
    </bean>

    内部匿名Bean

    <!-- 内部匿名bean -->
    <bean id="myStudent" class="com.neu.di12.Student" autowire="byType">
        <property name="name" value="js"></property>
        <property name="age" value="23"></property>
        <property name="school">
            <bean class="com.neu.di12.School">
                <property name="sname" value="neu"></property>
            </bean>
        </property>
    </bean>

    使用同类抽象 Bean 注入

    当若干的 Bean 实例同属于一个类,这些实例的属性值又有相同值,我们考虑使用抽象 Bean 来避免冗余,简化配置文件

    抽象 Bean 是用于让其他的 bean 继承的。这个 bean 不能通过 getBean() 方法来获取,所以应该设置 abstract 属性为 true,其默认值是 false(不设置为抽象 Bean 也能被继承,但一般应该设置为抽象的)

    Student 的部分代码

    public class Student {
        private String name;
        private int age;
        private String school;
        private String department;
    <!-- 同类抽象Bean -->
    <bean id="baseStudent" class="com.neu.di13.Student" abstract="true">
        <property name="school" value="清华大学"></property>
        <property name="department" value="计算机学院"></property>
    </bean>
    <bean id="student1" parent="baseStudent">
        <property name="name" value="JS"></property>
        <property name="age" value="21"></property>
    </bean>
    <bean id="student2" parent="baseStudent">
        <property name="name" value="WY"></property>
        <property name="age" value="22"></property>
    </bean>
    <bean id="student3" parent="baseStudent">
        <property name="name" value="WX"></property>
        <property name="age" value="20"></property>
    </bean>

    使用异类抽象 Bean 注入

    这种注入应用的情况是若干不同类的对象具有相同的属性,值也相同时。

    Student 类的成员变量如之前的同类抽象一样

    这是 Teacher 的部分代码(年龄变成了工龄)

    public class Teacher {
        private String name;
        private int workAge;
        private String school;
        private String department;
    <!-- 异类抽象Bean -->
    <bean id="base" abstract="true">
        <property name="school" value="清华大学"></property>
        <property name="department" value="计算机学院"></property>
    </bean>
    <bean id="student" class="com.neu.di14.Student" parent="base">
        <property name="name" value="JS"></property>
        <property name="age" value="21"></property>
    </bean>
    <bean id="teacher" class="com.neu.di14.Teacher" parent="base">
        <property name="name" value="JS"></property>
        <property name="workAge" value="5"></property>
    </bean>
  • 相关阅读:
    向日葵、阳光
    laravel还是给我太多惊喜了
    滴滴笔试题——小试牛刀
    剑指offer——二叉搜索树的后序遍历序列
    2019春招美团笔试
    首次实习生招聘会——航天一院
    有趣的数字
    剑指offer——从上往下打印二叉树
    剑指offer——栈的压入、弹出序列
    剑指offer——包含min函数的栈
  • 原文地址:https://www.cnblogs.com/jiasq/p/8600731.html
Copyright © 2011-2022 走看看