Spring_DI_XML_02

简介: 欢迎移步博客查看-http://futaosmile.oschina.io/coder957基于XMl的DI1.集合属性注入2.array数组属性注入3.

欢迎移步博客查看-http://futaosmile.oschina.io/coder957

基于XMl的DI
1.集合属性注入
2.array数组属性注入
3.List<>属性注入
4.Set<>属性注入
5.Map<K,V>属性注入
6.Properties属性注入
7.autowire自动注入
8.SPEL注入

School类

package Part02.collectionDI;

/**
 * Created by futao on 2017/10/10.
 */
public class School {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                '}';
    }
}

Some类

package Part02.collectionDI;


import java.util.*;

/**
 * Created by futao on 2017/10/10.
 */
public class Some {
    private School[] schools;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,Object> myMap;
    private Properties myPro;

    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 setMyPro(Properties myPro) {
        this.myPro = myPro;
    }

    @Override
    public String toString() {
        return "Some{" +
                "schools=" + Arrays.toString(schools) +
                ", myList=" + myList +
                ", mySet=" + mySet +
                ", myMap=" + myMap +
                ", myPro=" + myPro +
                '}';
    }
}

配置文件applicationContextcollectionDI.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="some" class="Part02.collectionDI.Some">
        <!--数组-->
       <property name="schools">
           <array>
               <ref bean="school1"/>
               <ref bean="school2"/>
               <ref bean="school2"/>
               <ref bean="school2"/>
           </array>
       </property>

       <!--list-->
       <property name="myList">
           <list>
               <value>张三</value>
               <value>李四</value>
               <value>王五</value>
           </list>
       </property>
       <!--这种方式myList的长度为1,value里面的值会被当成一个值-->
       <!--<property name="myList" value="张三,李四,王五"/>-->

       <!--set-->
       <property name="mySet">
           <set>
               <value>北京</value>
               <value>上海</value>
               <value>南昌</value>
           </set>
       </property>
       <!--这种方式mySet的长度为1,value里面的值会被当成一个值-->
       <!--<property name="mySet" value="北京,上海,南昌"/>-->

       <!--map-->
       <property name="myMap">
           <map>
               <entry key="k1" value-ref="school1"/>
               <entry key="k2" value-ref="school2"/>
               <entry key="k3" value-ref="school2"/>
               <entry key="k4" value-ref="school2"/>
               <entry key="k5" value="wechat"/>
           </map>
       </property>

       <property name="myPro">
           <props>
               <prop key="地址1">上海市</prop>
               <prop key="地址2">闵行区</prop>
               <prop key="地址3">吴泾镇</prop>
               <prop key="地址4">紫竹</prop>
               <prop key="地址5">数码港</prop>
           </props>
       </property>

   </bean>

    <bean id="school1" class="Part02.collectionDI.School">
        <property name="name" value="Ecjtu"></property>
    </bean>
    <bean id="school2" class="Part02.collectionDI.School">
        <property name="name" value="NCDX"></property>
    </bean>
</beans>

测试

 /**
     * 基于XML的DI-集合属性注入
     */
    @Test
    fun test4collections(){
        val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextcollectionDI.xml")
        val some = classPathXmlApplicationContext.getBean("some") as Some
        println(GsonBuilder().setPrettyPrinting().create().toJson(some))
    }

结果

{
  "schools": [
    {
      "name": "Ecjtu"
    },
    {
      "name": "NCDX"
    },
    {
      "name": "NCDX"
    },
    {
      "name": "NCDX"
    }
  ],
  "myList": [
    "张三",
    "李四",
    "王二"
  ],
  "mySet": [
    "北京",
    "上海",
    "南昌"
  ],
  "myMap": {
    "k1": {
      "name": "Ecjtu"
    },
    "k2": {
      "name": "NCDX"
    },
    "k3": {
      "name": "NCDX"
    },
    "k4": {
      "name": "NCDX"
    },
    "k5": "wechat"
  },
  "myPro": {
    "地址3": "吴泾镇",
    "地址2": "闵行区",
    "地址1": "上海市",
    "地址5": "数码港",
    "地址4": "紫竹"
  }
}

autowire自动装配

School类

package Part02.autoDIbyNameForDomain;

/**
 * Created by futao on 2017/10/10.
 */
public class School {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "School{" +
                "name='" + name + '\'' +
                '}';
    }
}

Student类

package Part02.autoDIbyNameForDomain;

/**
 * Created by futao on 2017/10/10.
 */
public class Student {
    private String name;
    private int age;
    private String address;
    private School school;

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public School getSchool() {
        return school;
    }

    public void setSchool(School school) {
        this.school = school;
    }

    public Student() {
    }

    public Student(String name, int age, String address, School school) {
        this.name = name;
        this.age = age;
        this.address = address;
        this.school = school;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", school=" + school +
                '}';
    }
}

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="school1" class="Part02.autoDIbyNameForDomain.School">
        <property name="name" value="上海交通大学"/>
    </bean>

    <bean id="student" class="Part02.autoDIbyNameForDomain.Student" autowire="byName">
        <property name="age" value="18"/>
        <property name="address" value="Shanghai"/>
    </bean>
</beans>

测试

 /**
     * 基于XML的DI-byName方式的域属性自动注入
     */
    @Test
    fun test4autoDIbyNamefordomain() {
        val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextautoDIbyNameForDomain.xml")
        val student = classPathXmlApplicationContext.getBean("student") as Part02.autoDIbyNameForDomain.Student
//        serializeNulls()->为null的值也显示出来,setPrettyPrinting()->格式化控制台输出
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
        println(student)
    }

结果

{
  "name": null,
  "age": 18,
  "address": "Shanghai",
  "school": null
}
Student{name='null', age=18, address='Shanghai', school=null}

others

在xml配置文件中,autowire有5种类型,可以在<bean/>元素中使用autowire属性指定

<table>
<tr>
<td>模式</td>
<td>说明</td>
</tr>
<tr>
<td>no</td>
<td>不使用自动装配,必须通过ref元素指定依赖,默认设置。</td>
</tr>
<tr>
<td>byName</td>
<td> 根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。</td>
</tr>
<tr>
<td>byType</td>
<td> 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生,也可以通过设置dependency-check="objects"让Spring抛出异常。</td>
</tr>
<tr>
<td>constructor</td>
<td>与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常。</td>
</tr>
<tr>
<td>autodetect </td>
<td>通过bean类的自省机制(introspection)来决定是使用constructor还是byType方式进行自动装配。如果发现默认的构造器,那么将使用byType方式。 </td>
</tr>
</table>
可以设置bean使自动装配失效:
采用xml格式配置bean时,将<bean/>元素的autowire-candidate属性设置为false,这样容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其它bean自动装配的候选者,但是该bean本身还是可以使用自动装配来注入其它bean的。

需要注意以下情况:
autowird="byType" (type->A)
B extends A
A是一个bean
如果此时B也是一个bean,则会报错,该类型(A)的bean不止一个。
因为A a=new B()
B类型也可以作为A类型根据autowird="byType"进行注入

SPEL注入

Person类

package Part02.SPELDI;

/**
 * Created by futao on 2017/10/11.
 */
public class Person {
    /**
     * 姓名
     */
    private String pname;
    /**
     * 年龄
     */
    private int page;

    /**
     * 带参构造方法
     *
     * @param pname 姓名
     * @param page  年龄
     */
    public Person(String pname, int page) {
        this.pname = pname;
        this.page = page;
    }

    public Person() {
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    @Override
    public String toString() {
        return "Person{" +
                "pname='" + pname + '\'' +
                ", page=" + page +
                '}';
    }

    /**
     * 控制年龄
     *
     * @return
     */
    public int calculateAge() {
        return page > 25 ? 25 : page;
    }
}

Student类

package Part02.SPELDI;

/**
 * Created by futao on 2017/10/12.
 */
public class Student {
    private String sname;
    private int sage;

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public int getSage() {
        return sage;
    }

    public void setSage(int sage) {
        this.sage = sage;
    }

    @Override
    public String toString() {
        return "Student{" +
                "sname='" + sname + '\'' +
                ", sage=" + sage +
                '}';
    }

}

配置文件

<?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="person" class="Part02.SPELDI.Person">
        <property name="pname" value="老三"/>
        <property name="page" value="#{T(java.lang.Math).random()*50}"/>
    </bean>
    <bean id="student" class="Part02.SPELDI.Student">
        <property name="sname" value="#{person.pname}"/>
        <!--<property name="sage" value="#{person.page > 25 ? 25:person.page}"/>-->
        <property name="sage" value="#{person.calculateAge()}"/>
    </bean>
</beans>

测试

    /**
     * SPEL注入
     */
    @Test
    fun test4SPEL(){
        val classPathXmlApplicationContext = ClassPathXmlApplicationContext("applicationContextSPEL.xml")
        val student = classPathXmlApplicationContext.getBean("student") as Part02.SPELDI.Student
        val person = classPathXmlApplicationContext.getBean("person") as Person
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))

        student.sage=666
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))

        person.page=999
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(student))
        println(GsonBuilder().serializeNulls().setPrettyPrinting().create().toJson(person))

    }

结果

{
  "sname": "老三",
  "sage": 25
}
{
  "pname": "老三",
  "page": 29
}
{
  "sname": "老三",
  "sage": 666
}
{
  "pname": "老三",
  "page": 29
}
{
  "sname": "老三",
  "sage": 666
}
{
  "pname": "老三",
  "page": 999
}

tips:

如果一个类有带参的构造函数,而没有无参的构造函数,那么在注册bean的时候必须使用构造注入。

目录
相关文章
|
7月前
|
Java Spring
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
Spring5深入浅出篇:Spring中ioc(控制反转)与DI(依赖注入)
|
7月前
|
Java API Spring
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
Spring6-IoC(Inversion of Control)控制反转和DI(Dependency Injection)依赖注入,手动实现IOC
|
7月前
|
XML Java 数据格式
Spring框架入门:IoC与DI
【5月更文挑战第15天】本文介绍了Spring框架的核心特性——IoC(控制反转)和DI(依赖注入)。IoC通过将对象的创建和依赖关系管理交给容器,实现解耦。DI作为IoC的实现方式,允许外部注入依赖对象。文章讨论了过度依赖容器、配置复杂度等常见问题,并提出通过合理划分配置、使用注解简化管理等解决策略。同时,提醒开发者注意过度依赖注入和循环依赖,建议适度使用构造器注入和避免循环引用。通过代码示例展示了注解实现DI和配置类的使用。掌握IoC和DI能提升应用的灵活性和可维护性,实践中的反思和优化至关重要。
434 4
|
2月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
41 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
2月前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
40 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
3月前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
3月前
|
Java 数据库连接 Maven
Spring基础1——Spring(配置开发版),IOC和DI
spring介绍、入门案例、控制反转IOC、IOC容器、Bean、依赖注入DI
Spring基础1——Spring(配置开发版),IOC和DI
|
6月前
|
存储 Java 测试技术
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性
45 1
|
6月前
|
存储 Java 程序员
Spring IoC&DI(2)—IoC详解
Spring IoC&DI(2)—IoC详解
53 2
|
6月前
|
存储 Java C++
理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory
理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory