• Spring框架第三篇之基于XML的DI注入


    一、注入分类

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

    1、设值注入

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

    关于设值注入举个简单的例子:

    分别创建一个学校类(School):

    /**
     * 学校类
     * 
     * @author Root
     */
    public class School {
        
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "School [name=" + name + "]";
        }
        
    }

    学生类(Student):

    /**
     * 学生类
     * 
     * @author Root
     */
    public class Student {
    
        private String name;
        private int age;
        // 对象属性,也叫做域属性
        private School school;
    
        public Student() {
            super();
        }
    
        public void setName(String name) {
            System.out.println("执行setName()");
            this.name = name;
        }
    
        public void setAge(int age) {
            System.out.println("执行setAge()");
            this.age = age;
        }
    
        public void setSchool(School school) {
            this.school = school;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", school=" + school + "]";
        }
    
    }

    在配置文件中使用设值注入方式,设值对象属性值:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <bean id="school" class="com.ietree.spring.basic.di.setter.School">
            <property name="name" value="北京大学"></property>
        </bean>
        
        <!-- 注册Student -->
        <bean id="student" class="com.ietree.spring.basic.di.setter.Student">
            <property name="name" value="李华"></property>
            <property name="age" value="20"></property>
            <!-- 域属性注入使用ref -->
            <property name="school" ref="school"></property>
        </bean>
        
    </beans>

    注意:如果对象中包含有另外的对象引用,则需要使用ref,而不能使用value。

    测试:

    @Test
    public void test01(){
            
        String resource = "com/ietree/spring/basic/di/setter/applicationContext.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(resource);
            
        Student student = (Student) ctx.getBean("student");
        System.out.println(student);
    }

    程序输出:

    执行setName()
    执行setAge()
    Student [name=李华, age=20, school=School [name=北京大学]]

    2、构造注入

     构造注入,顾名思义就是通过构造方法注入,举个简单的例子:

    创建一个学校类(School):

    /**
     * 学校类
     * 
     * @author Root
     */
    public class School {
        
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "School [name=" + name + "]";
        }
        
    }

    学生类(Student):

    /**
     * 学生类
     * 
     * @author Root
     */
    public class Student {
    
        private String name;
        private int age;
        // 对象属性,也叫做域属性
        private School school;
    
        /*public Student() {
            super();
        }*/
    
        // 代参构造器
        public Student(String name, int age, School school) {
            super();
            this.name = name;
            this.age = age;
            this.school = school;
        }
    
        public void setName(String name) {
            System.out.println("执行setName()");
            this.name = name;
        }
    
        public void setAge(int age) {
            System.out.println("执行setAge()");
            this.age = age;
        }
    
        public void setSchool(School school) {
            this.school = school;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", school=" + school + "]";
        }
    
    }

    配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <bean id="school" class="com.ietree.spring.basic.di.constructor.School">
            <property name="name" value="北京大学"></property>
        </bean>
        
        <!-- 注册Student -->
        <!-- 方式一 -->
        <!-- <bean id="student" class="com.ietree.spring.basic.di.constructor.Student">
            <constructor-arg index="0" value="李华"/>
            <constructor-arg index="1" value="20"/>
            <constructor-arg index="2" ref="school"/>
        </bean> -->
        
        <!-- 方式二 -->
        <!-- <bean id="student" class="com.ietree.spring.basic.di.constructor.Student">
            <constructor-arg value="李华"/>
            <constructor-arg value="20"/>
            <constructor-arg ref="school"/>
        </bean> -->
        
        <!-- 方式三:推荐-->
        <bean id="student" class="com.ietree.spring.basic.di.constructor.Student">
            <constructor-arg name="name" value="李华"/>
            <constructor-arg name="age" value="20"/>
            <constructor-arg name="school" ref="school"/>
        </bean>
        
    </beans>

    个人强烈推荐使用方式三,因为这样的配置方式不会带来歧义,关键是可读性比强两者要强。

    测试:

    @Test
    public void test01(){
            
        String resource = "com/ietree/spring/basic/di/constructor/applicationContext.xml";
        ApplicationContext ctx = new ClassPathXmlApplicationContext(resource);
            
        Student student = (Student) ctx.getBean("student");
        System.out.println(student);
    }

    程序输出:

    Student [name=李华, age=20, school=School [name=北京大学]]

    二、命名空间注入

     命名空间注入分为两种,p命名空间和c命名空间。

    例:

    创建School类:

    /**
     * 学校类
     * 
     * @author Root
     */
    public class School {
        
        private String name;
    
        public School(String name) {
            super();
            this.name = name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "School [name=" + name + "]";
        }
        
    }

    创建学生类(Student):

    /**
     * 学生类
     * 
     * @author Root
     */
    public class Student {
    
        private String name;
        private int age;
        // 对象属性,也叫做域属性
        private School school;
    
        public Student() {
            super();
        }
    
        public Student(String name, int age, School school) {
            super();
            this.name = name;
            this.age = age;
            this.school = school;
        }
    
        public void setName(String name) {
            System.out.println("执行setName()");
            this.name = name;
        }
    
        public void setAge(int age) {
            System.out.println("执行setAge()");
            this.age = age;
        }
    
        public void setSchool(School school) {
            this.school = school;
        }
    
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + ", school=" + school + "]";
        }
    
    }

    配置文件:

    <?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:p="http://www.springframework.org/schema/p"
        
        xmlns:c="http://www.springframework.org/schema/c"
        
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <!-- <bean id="mySchool" class="com.ietree.spring.basic.di.namespace.School" p:name="清华大学"/>
        
        注册Student
        <bean id="student" class="com.ietree.spring.basic.di.namespace.Student" p:name="李华" p:age="20" p:school-ref="mySchool"/> -->
        
        <!-- 注册School -->
        <bean id="mySchool" class="com.ietree.spring.basic.di.namespace.School" c:name="清华大学"/>
        
        <!-- 注册Student -->
        <bean id="student" class="com.ietree.spring.basic.di.namespace.Student" c:name="李华" c:age="20" c:school-ref="mySchool"/>
        
    </beans>

    注意:

    1、这里如果要想使用这两种命名空间方式的话,需要先导入约束:

    xmlns:p="http://www.springframework.org/schema/p"

    xmlns:c="http://www.springframework.org/schema/c"

    2、如果是使用c命名空间的方式的话,在类里面还必须写上带参构造器。

    三、集合属性注入

     创建School类:

    /**
     * 学校类
     * 
     * @author Root
     */
    public class School {
        
        private String name;
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "School [name=" + name + "]";
        }
        
    }

    创建Some类:

    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 String[] myStr;
        private List<String> myList;
        private Set<String> mySet;
        private Map<String, Object> myMap;
        private Properties myProps;
    
        public void setSchools(School[] schools) {
            this.schools = schools;
        }
    
        public void setMyStr(String[] myStr) {
            this.myStr = myStr;
        }
    
        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 setMyProps(Properties myProps) {
            this.myProps = myProps;
        }
    
        @Override
        public String toString() {
            return "Some [schools=" + Arrays.toString(schools) + ", myStr=" + Arrays.toString(myStr) + ", myList=" + myList
                    + ", mySet=" + mySet + ", myMap=" + myMap + ", myProps=" + myProps + "]";
        }
    
    }

    配置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"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <bean id="mySchool" class="com.ietree.spring.basic.di.list.School">
            <property name="name" value="北京大学"></property>
        </bean>
        <bean id="mySchool2" class="com.ietree.spring.basic.di.list.School">
            <property name="name" value="清华大学"></property>
        </bean>
        
        <!-- 注册Student -->
        <bean id="some" class="com.ietree.spring.basic.di.list.Some">
            <property name="schools">
                <array>
                    <ref bean="mySchool"/>
                    <ref bean="mySchool2"/>
                </array>
            </property>
            <property name="myStr">
                <array>
                    <value>中国</value>
                    <value>广东</value>
                </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="mobile" value="123456"></entry>
                    <entry key="weChat" value="654321"></entry>
                </map>
            </property>
            <property name="myProps">
                <props>
                    <prop key="edu">本科</prop>
                    <prop key="gender">性别</prop>
                </props>
            </property>
        </bean>
        
    </beans>

    方式二:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <bean id="mySchool" class="com.ietree.spring.basic.di.list.School">
            <property name="name" value="北京大学"></property>
        </bean>
        <bean id="mySchool2" class="com.ietree.spring.basic.di.list.School">
            <property name="name" value="清华大学"></property>
        </bean>
        
        <!-- 注册Student -->
        <bean id="some" class="com.ietree.spring.basic.di.list.Some">
            <property name="schools">
                <array>
                    <ref bean="mySchool"/>
                    <ref bean="mySchool2"/>
                </array>
            </property>
            
            <property name="myStr" value="中国,广东"/>
            
            <property name="myList" value="深圳,龙岗"/>
            
            <property name="mySet" value="坂田,天安云谷"/>
            
            <property name="myMap">
                <map>
                    <entry key="mobile" value="123456"></entry>
                    <entry key="weChat" value="654321"></entry>
                </map>
            </property>
            <property name="myProps">
                <props>
                    <prop key="edu">本科</prop>
                    <prop key="gender">性别</prop>
                </props>
            </property>
        </bean>
        
    </beans>

    四、对于域属性的自动注入

    <!-- 注册Student 
            autowire="byName":通过字段名注入
            autowire="byType":通过字段类型注入
    -->
    <bean id="student" class="com.ietree.spring.basic.di.domain.Student" autowire="byName">
        <property name="name" value="李华"></property>
        <property name="age" value="20"></property>
    </bean>

    五、使用SPEL注入

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

    举例:

    创建Person类:

    package com.ietree.spring.basic.di.spel;
    
    public class Person {
    
        private String pname;
    
        private int page;
    
        public Person() {
            super();
        }
    
        public void setPname(String pname) {
            this.pname = pname;
        }
    
        public void setPage(int page) {
            this.page = page;
        }
    
        public String getPname() {
            return pname;
        }
    
        public int getPage() {
            return page;
        }
        
        public int computeAge() {
            return this.page > 25 ? 25 : this.page;
        }
        
        @Override
        public String toString() {
            return "Person [pname=" + pname + ", page=" + page + "]";
        }
    
    }

    创建Student类:

    package com.ietree.spring.basic.di.spel;
    
    /**
     * 学生类
     * 
     * @author Root
     */
    public class Student {
    
        private String name;
    
        private int age;
    
        public Student() {
            super();
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Student [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"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <bean id="myPerson" class="com.ietree.spring.basic.di.spel.Person">
            <property name="pname" value="李华"></property>
    <!-- 随机生成0 - 99数字 -->
    <property name="page" value="#{T(java.lang.Math).random() * 100}"></property> </bean> <bean id="myStudent" class="com.ietree.spring.basic.di.spel.Student"> <property name="name" value="#{myPerson.pname}"></property> <!-- <property name="age" value="#{myPerson.page > 25 ? 25 : myPerson.page}"></property> --> <property name="age" value="#{myPerson.computeAge() }"></property> </bean> </beans>

    六、使用内部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"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 注册School -->
        <!-- <bean id="school" class="com.ietree.spring.basic.di.inner.School">
            <property name="name" value="北京大学"></property>
        </bean> -->
        
        <!-- 注册Student -->
        <bean id="student" class="com.ietree.spring.basic.di.inner.Student">
            <property name="name" value="李华"></property>
            <property name="age" value="20"></property>
            <property name="school">
                <bean class="com.ietree.spring.basic.di.inner.School">
                    <property name="name" value="清华大学"></property>
                </bean>
            </property>
        </bean>
        
    </beans>

    七、使用同类抽象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"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 同类抽象Bean -->
        <bean id="baseStudent" class="com.ietree.spring.basic.di.sameextends.Student" abstract="true">
            <property name="school" value="清华大学"/>
            <property name="department" value="计算机系"/>
        </bean>
        <bean id="student1" parent="baseStudent">
            <property name="name" value="小明"/>
            <property name="age" value="21"/>
        </bean>
        <bean id="student2" parent="baseStudent">
            <property name="name" value="张三"/>
            <property name="age" value="22"/>
        </bean>
        <bean id="student3" parent="baseStudent">
            <property name="name" value="李四"/>
            <property name="age" value="23"/>
        </bean>
        
    </beans>

    八、使用异类抽象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"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        <!-- 异类抽象Bean -->
        <bean id="baseStudent" abstract="true">
            <property name="school" value="清华大学"/>
            <property name="department" value="计算机系"/>
        </bean>
        
        <bean id="student" class="com.ietree.spring.basic.di.sameextends.Student" parent="baseStudent">
            <property name="name" value="小明"/>
            <property name="age" value="21"/>
        </bean>
        <bean id="teacher" class="com.ietree.spring.basic.di.sameextends.Teacher" parent="baseStudent">
            <property name="name" value="李四"/>
            <property name="age" value="23"/>
        </bean>
        
    </beans>

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

     1、同级关系:

    测试:

    package com.ietree.spring.basic.di.mulxml;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class MyTest {
    
        @Test
        public void test01() {
    
            /*String resource1 = "com/ietree/spring/basic/di/setter/spring-base.xml";
            String resource2 = "com/ietree/spring/basic/di/setter/spring-beans.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(resource1, resource2);*/
            
            String resource = "com/ietree/spring/basic/di/setter/spring-*.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(resource);
    
            Student student = (Student) ctx.getBean("student");
            System.out.println(student);
        }
    
    }

    2、包含关系:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <import resource="classpath:com/ietree/spring/basic/di/mulxml/spring-base.xml"/>
        <import resource="classpath:com/ietree/spring/basic/di/mulxml/spring-beans.xml"/>
    </beans>
  • 相关阅读:
    Javascript引擎的单线程机制和setTimeout执行原理阐述
    给定红包个数和红包金额,计算红包的金额
    oracle日志归档空间清理
    Jmeter之录制控制器与代理的使用
    Jmeter分布式测试的坑
    Jmeter之Cookie和Session处理
    性能测试之JMeter远程模式
    JMeter自带工具录制配置方法
    Jmeter分布式测试
    性能测试的 Check List (不断更新中)
  • 原文地址:https://www.cnblogs.com/Dylansuns/p/7045497.html
Copyright © 2020-2023  润新知