Dependency Injection,依赖注入。
  • 对象之间依赖关系的管理交给 Spring 维护;

  • 是实现控制反转的方式之一;

  • 可以降低程序之间的耦合(依赖关系)。


Spring 实现的 IoC 容器中,基本类型和对象都可以注入,按配置细节区分:

  • Java 基本类型

  • String

  • bean

  • Spring 自建 bean(未自己申明的 bean,可以通过 getBean 方法获取到)

  • 非 bean(无法通过 getBean 方法获取到)

  • 数组

  • 集合(List、Set、Map)


使用 setter 方法演示以上数据类型的注入


bean 的类

package constxiong.datatype;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class User {

    private double id;

    private String name;

    private User wife;

    private User[] friends;

    private List<User> schoolmates;

    private Set<String> favorites;

    private Map<String, String> emails;

    public void setId(double id) {
        this.id = id;
    }

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

    public void setWife(User wife) {
        this.wife = wife;
    }

    public void setFriends(User[] friends) {
        this.friends = friends;
    }

    public void setSchoolmates(List<User> schoolmates) {
        this.schoolmates = schoolmates;
    }

    public void setFavorites(Set<String> favorites) {
        this.favorites = favorites;
    }

    public void setEmails(Map<String, String> emails) {
        this.emails = emails;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", wife=" + wife + ", friends=" + Arrays.toString(friends)
                + ", schoolmates=" + schoolmates + ", favorites=" + favorites + ", emails=" + emails + "]";
    }

}


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="wife" class="constxiong.datatype.User">
        <property name="id" value="2"/>
        <property name="name" value="wife"/>
    </bean>

    <bean id="ConstXiong" class="constxiong.datatype.User">
        <property name="id" value="1"/>
        <property name="name" value="ConstXiong"/>
        <property name="wife" ref="wife"/>
        <property name="friends">
            <list>
                <ref bean="wife"/>
            </list>
        </property>
        <property name="schoolmates">
            <list>
                <ref bean="wife"/>
            </list>
        </property>
        <property name="favorites">
            <set>
                <value>写代码</value>
                <value>睡觉</value>
            </set>
        </property>
        <property name="emails">
            <map>
                <entry key="公司" value="123@123.com"></entry>
                <entry key="个人" value="123@abc.com"></entry>
            </map>
        </property>
    </bean>

</beans>


测试代码

package constxiong.datatype;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 依赖注入-可注入的数据类型
 */

public class Test {

    @SuppressWarnings("resource")
    public static void main(String[] args) {
        BeanFactory factory = new ClassPathXmlApplicationContext("META-INF/spring-dependency-injection-datatype.xml");
        User constxiong = (User)factory.getBean("ConstXiong");
        System.out.println(constxiong);
    }

}


结果打印

User [id=1.0, name=ConstXiong, wife=User [id=2.0, name=wife, wife=null, friends=null, schoolmates=null, favorites=null, emails=null], friends=[User [id=2.0, name=wife, wife=null, friends=null, schoolmates=null, favorites=null, emails=null]], schoolmates=[User [id=2.0, name=wife, wife=null, friends=null, schoolmates=null, favorites=null, emails=null]], favorites=[写代码, 睡觉], emails={公司=123@123.com, 个人=123@abc.com}]


上面这个例子演示了基本类型 double、String、bean、数组、List、Set、Map 的注入,不难看懂,不多解释。



那什么是 Spring 自建的 bean 和 非 bean 呢?这两个概念,看下面这个例子。


新增类 SpecialUser,包含了 BeanFactory 和 Environment 两个类型的属性

package constxiong.datatype;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.env.Environment;

public class SpecialUser {

    private BeanFactory beanFactory;

    private Environment environment;

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public Environment getEnvironment() {
        return environment;
    }

    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }

}


xml 新增一个 bean 配置

<bean id="specialUser" class="constxiong.datatype.SpecialUser" autowire="byType">
</bean>


测试类的 main 方法中新增测试代码

SpecialUser specialUser = (SpecialUser)factory.getBean("specialUser");
//Spring 自建 bean,并未在 spring-dependency-injection-datatype.xml 配置文件中申明,却可以注入与依赖查找
System.out.println(specialUser.getEnvironment());//通过 autowire="byType" 可以注入成功
System.out.println(factory.getBean(Environment.class));

//非 bean,可以注入,但无法通过 getBean 方法依赖查找
System.out.println(specialUser.getBeanFactory());//通过 autowire="byType" 可以注入成功
System.out.println(factory.getBean(BeanFactory.class));//getBean 方法无法获取到 BeanFactory


打印结果

StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[PropertiesPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}]}
StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[PropertiesPropertySource {name='systemProperties'}, SystemEnvironmentPropertySource {name='systemEnvironment'}]}
org.springframework.beans.factory.support.DefaultListableBeanFactory@3498ed: defining beans [wife,ConstXiong,specialUser]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.beans.factory.BeanFactory' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1126)
    at constxiong.datatype.Test.main(Test.java:26)


从打印结果可以看出

  • Environment bean 并未在 xml 中配置,但却可以注入与通过 getBean 方法依赖查找,即上面提到的 Spring 自建的 bean
  • BeanFactory 可以被注入,但通过 getBean 方法获取报找不到 bean 的错误,即上面提到的非 bean


ps:
文末引出的自建 bean 与非 bean 还包含哪些类?依赖注入又有哪些实现方式?

限于篇幅,后续研究。


更多相关文章

  1. 模板方法模式在开源代码中应用
  2. 构造方法的参数太多,如何解决?
  3. c语言数据类型(初学)
  4. 面试官:为什么静态方法不能调用非静态方法和变量?
  5. ConcurrentHashMap之size()方法

随机推荐

  1. android网络编程——使用Android中的网络
  2. Android Studio:AndroidX的迁移
  3. Android 中自定义View(三)
  4. android app模拟 persistent 属性可以保
  5. android ndk 开发之 在 应用程序中使用 j
  6. [置顶] android调用第三方库——第二篇—
  7. Relativelayout的一些属性
  8. Android摄像头照相机技术-android学习之
  9. Android XMl文件中tools前缀
  10. android Textview过长时显示省略号