美文网首页spring
Spring--xml方式实现DI

Spring--xml方式实现DI

作者: aruba | 来源:发表于2022-05-18 13:34 被阅读0次

    作为SSM框架中的一个,Spring框架和Dagger一样,它是一个IOC容器,除此以外还支持AOP编程。关于IOC,安卓开发中已经介绍过了,简单来说,对象的生产和生命周期的管理都交由容器实现,我们在用到的地方直接注入(DI)即可使用,省去了程序员重复编写创建对象的操作。后期一般使用注解注入,配合apt+javapoet+javassisit可以完全交由注解实现,不需要写xml
    xml实现di为最基础的操作,通过编写xml文件,指定生成的对象规则,最后由自定义xml解析器解析xml,并将对象放入容器中,通过容器即可获取对象或者重新生成新对象

    一、Spring初步使用

    导入依赖:

            <!--包含了一系列组件-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.3.5</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13.1</version>
                <scope>test</scope>
            </dependency>
    

    新建一个实体类:

    public class User {
        private Integer uid;
        private String username;
        private String password;
    
        public User() {
        }
    
        public User(Integer uid, String username, String password) {
            this.uid = uid;
            this.username = username;
            this.password = password;
        }
    
        public Integer getUid() {
            return uid;
        }
    
        public void setUid(Integer uid) {
            this.uid = uid;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "uid=" + uid +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    '}';
        }
    }
    

    在resources目录下创建一个xml文件:



    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="user" class="com.aruba.bean.User"></bean>
    </beans>
    

    测试方法:

        @org.junit.Test
        public void test1() {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
            User user = applicationContext.getBean("user", User.class);
            System.out.println(user);
        }
    

    运行结果:


    二、bean标签属性

    <bean id="user" class="com.aruba.bean.User" scope="prototype" lazy-init="true" ></bean>
    
    • id:获取对象时的key
    • class:全类名
    • scope:作用域
      singleton 表示全局只有一个,即单例
      prototype 表示每次获取都创建一个新的对象
    • lazy-init:是否开启懒加载,开启后只有在获取对象时才会实例化对象

    三、对象属性为基本类型的赋值

    1. 构造函数传参

    可以通过constructor-arg标签,指定构造函数中的传参:

        <bean id="user2" class="com.aruba.bean.User">
            <constructor-arg name="username" value="xiaoming"></constructor-arg>
            <constructor-arg name="uid" value="1"></constructor-arg>
            <constructor-arg index="2" value="123456"></constructor-arg>
        </bean>
    

    其中name属性对应实体类中的属性名,index属性则对应传参索引

    可以通过constructor-arg标签的命名空间简化标签:

    xmlns:c="http://www.springframework.org/schema/c"
    
    2. 设置属性传参

    可以通过property标签设置对象的属性:

        <bean id="user3" class="com.aruba.bean.User">
            <property name="username" value="赵四"/>
            <property name="uid" value="4"/>
            <property name="password" value="54321"/>
        </bean>
    

    name属性最终是利用反射调用set方法,如果实体类里没有定义对应的set方法,则报错

    property标签也可以通过命名空间简化:

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

    四、bean引用

    上面我们只是对基本类型数据进行了传递和设置,现在给User类新增一个Job的属性

    新建Job实体类:

    public class Job {
        private Integer jid;
        private String jobName;
        private String jobDescription;
    
        public Job() {
        }
    
        @Override
        public String toString() {
            return "Job{" +
                    "jid=" + jid +
                    ", jobName='" + jobName + '\'' +
                    ", jobDescription='" + jobDescription + '\'' +
                    '}';
        }
    
        public Integer getJid() {
            return jid;
        }
    
        public void setJid(Integer jid) {
            this.jid = jid;
        }
    
        public String getJobName() {
            return jobName;
        }
    
        public void setJobName(String jobName) {
            this.jobName = jobName;
        }
    
        public String getJobDescription() {
            return jobDescription;
        }
    
        public void setJobDescription(String jobDescription) {
            this.jobDescription = jobDescription;
        }
    
        public Job(Integer jid, String jobName, String jobDescription) {
            this.jid = jid;
            this.jobName = jobName;
            this.jobDescription = jobDescription;
        }
    }
    

    User中新增Job属性:

    public class User {
        private Integer uid;
        private String username;
        private String password;
        private Job job;
    
        public User() {
        }
    
        public User(Integer uid, String username, String password) {
            this.uid = uid;
            this.username = username;
            this.password = password;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "uid=" + uid +
                    ", username='" + username + '\'' +
                    ", password='" + password + '\'' +
                    ", job=" + job +
                    '}';
        }
    
        public User(Integer uid, String username, String password, Job job) {
            this.uid = uid;
            this.username = username;
            this.password = password;
            this.job = job;
        }
    
        public Integer getUid() {
            return uid;
        }
    
        public void setUid(Integer uid) {
            this.uid = uid;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public Job getJob() {
            return job;
        }
    
        public void setJob(Job job) {
            this.job = job;
        }
    }
    
    1. 外部引用

    xml中定义一个job的bean

        <bean id="job" class="com.aruba.bean.Job" c:_0="1" c:jobName="salesman" c:jobDescription="sale"></bean>
    
        <bean id="user6" class="com.aruba.bean.User" p:username="赵武" p:uid="6" p:password="789456">
            <property name="job" ref="job"></property>
        </bean>
    

    使用ref指定外部bean

    2. 内部引用

    bean可以直接在内部创建

        <bean id="user7" class="com.aruba.bean.User" p:username="赵武" p:uid="6" p:password="789456">
            <property name="job">
                <bean class="com.aruba.bean.Job" c:_0="1" c:jobName="salesman" c:jobDescription="sale"></bean>
            </property>
        </bean>
    
    3. 级联引用

    外部bean可以在内部设置属性

        <bean id="job2" class="com.aruba.bean.Job"></bean>
    
        <bean id="user8" class="com.aruba.bean.User" p:username="赵武" p:uid="6" p:password="789456">
            <property name="job" ref="job2"></property>
            <property name="job.jid" value="2"></property>
            <property name="job.jobName" value="algorithm"></property>
            <property name="job.jobDescription" value="algorithm"></property>
        </bean>
    

    五、集合注入

    新建一个Skill类:

    public class Skill {
        private Integer skilLId;
        private String skilLName;
    
        @Override
        public String toString() {
            return "Skill{" +
                    "skilLId=" + skilLId +
                    ", skilLName='" + skilLName + '\'' +
                    '}';
        }
    
        public Integer getSkilLId() {
            return skilLId;
        }
    
        public void setSkilLId(Integer skilLId) {
            this.skilLId = skilLId;
        }
    
        public String getSkilLName() {
            return skilLName;
        }
    
        public void setSkilLName(String skilLName) {
            this.skilLName = skilLName;
        }
    
        public Skill(Integer skilLId, String skilLName) {
            this.skilLId = skilLId;
            this.skilLName = skilLName;
        }
    
        public Skill() {
        }
    }
    

    User类中添加以下属性,其他代码就不展示了:

        private String[] skills;
        private Skill[] skills2;
        private List<Skill> skillList;
        private Set<Skill> skillSet;
        private Map<String,Skill> skillMap;
    
    1. 数组属性注入

    对于字符串或者基本类型的数组:

        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skills">
                <array>
                    <value>JAVA</value>
                    <value>PYTHON</value>
                    <value>GO</value>
                </array>
            </property>
        </bean>
    

    数组使用array标签,并且直接使用value

    引用类型数组:

        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skills2">
                <array>
                    <bean class="com.aruba.bean.Skill" c:_0="1" c:_1="JAVA"/>
                    <bean class="com.aruba.bean.Skill" c:_0="2" c:_1="PYTHON"/>
                    <bean class="com.aruba.bean.Skill" c:_0="3" c:_1="GO"/>
                </array>
            </property>
        </bean>
    

    也可以注入外部引用:

        <bean id="skill1" class="com.aruba.bean.Skill" c:_0="1" c:_1="JAVA"/>
        <bean id="skill2" class="com.aruba.bean.Skill" c:_0="2" c:_1="PYTHON"/>
        <bean id="skill3" class="com.aruba.bean.Skill" c:_0="3" c:_1="GO"/>
    
        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skills2">
                <array>
                    <ref bean="skill1"/>
                    <ref bean="skill2"/>
                    <ref bean="skill3"/>
                </array>
            </property>
        </bean>
    
    2. list集合注入

    使用list标签:

        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skillList">
                <list>
                    <bean class="com.aruba.bean.Skill" c:_0="1" c:_1="JAVA"/>
                    <bean class="com.aruba.bean.Skill" c:_0="2" c:_1="PYTHON"/>
                    <bean class="com.aruba.bean.Skill" c:_0="3" c:_1="GO"/>
                </list>
            </property>
        </bean>
    

    其他用法和array相同

    3. set集合注入
        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skillList">
                <set>
                    <bean class="com.aruba.bean.Skill" c:_0="1" c:_1="JAVA"/>
                    <bean class="com.aruba.bean.Skill" c:_0="2" c:_1="PYTHON"/>
                    <bean class="com.aruba.bean.Skill" c:_0="3" c:_1="GO"/>
                </set>
            </property>
        </bean>
    
    4. map注入
        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skillMap">
                <map>
                    <entry key="JAVA" value-ref="skill1"/>
                    <entry key="PYTHON" value-ref="skill2"/>
                    <entry key="GO" value-ref="skill3"/>
                </map>
            </property>
        </bean>
    
    5. 定义外部list集合

    引入util命名空间:

    定义外部list并使用

        <util:list id="sklist">
            <bean id="skill1" class="com.aruba.bean.Skill" c:_0="1" c:_1="JAVA"/>
            <bean id="skill2" class="com.aruba.bean.Skill" c:_0="2" c:_1="PYTHON"/>
            <bean id="skill3" class="com.aruba.bean.Skill" c:_0="3" c:_1="GO"/>
        </util:list>
    
        <bean id="user9" class="com.aruba.bean.User" p:username="王五" p:uid="7" p:password="789456">
            <property name="skillList" ref="sklist"></property>
        </bean>
    

    六、自定义工厂

    新建Java工厂类,实现FactoryBean接口:

    public class JobFactory implements FactoryBean<Job> {
        @Override
        public Job getObject() throws Exception {
            Job job = new Job(5, "MANAGER", "MANAGER");
            return job;
        }
    
        @Override
        public Class<?> getObjectType() {
            return null;
        }
    }
    

    xml中配置bean:

        <bean id="job10" class="com.aruba.factory.JobFactory"/>
    

    java中通过容器获取:

        @org.junit.Test
        public void test1() {
            Job job = applicationContext.getBean("job10", Job.class);
            System.out.println(job);
        }
    

    这边是直接获取的Job对象,并不是JobFactory

    Spring的xml方式实现di就到此结束了

    项目地址:

    https://gitee.com/aruba/spring-study.git

    相关文章

      网友评论

        本文标题:Spring--xml方式实现DI

        本文链接:https://www.haomeiwen.com/subject/xkoourtx.html