Spring 依赖注入

依赖注入的方式

Spring Ioc容器如何注入Bean的依赖资源。 具体解释:

主要包括:

  1. 构造器注入: 容器实例化时Bean时注入的依赖。是通过在Bean定义中指定构造器参数进行注入依赖。包括实例工厂方法参数注入依赖。但静态工厂方法参数不允许注入依赖???Why。
  2. Setter注入: 通过Setter方法进行注入依赖。

具体实现:

1. 构造器注入: 通过配置构造器参数实现,构造器参数就是依赖。

(图片来自其他地方,觉得很好理解)
这里写图片描述
构造器类: 构造器注入/静态工厂/实例工厂方式见上一章

 public class HelloImpl3 implements HelloApi {  
    private String message;  
private int index;  
//@java.beans.ConstructorProperties({"message", "index"})  
    public HelloImpl3(String message, int index) {  
        this.message = message;  
        this.index = index;  
    }  
    @Override  
    public void sayHello() {  
        System.out.println(index + ":" + message);  
    }  
}  
  • 可以使用index/type/参数name来注入。
<constructor-arg index="0" value = "hello"/> 
<constructor-arg index="1" value = "1"/> 

<constructor-arg type="java.lang.String" value = "hello"/> 
<constructor-arg type="int" value = "1"/> 

<constructor-arg name="message" value = "hello"/> 
<constructor-arg name="index" value = "1"/> 
  • 可以使用注解来注入依赖
    在构造器上添加@java.beans.ConstructorProperties({“message”, “index”})
    To Do—-待深入
2. Setter注入:

是通过构造器/静态工厂/实例工厂等实例化bean之后,通过使用set方法注入依赖。
这里写图片描述
Setter方式实际根据set名字注入的,例如setMessage则

<property name="message" value="Hello"/>

其中property说明是使用的setter方式注入,而message指的是setMessage方法。

JavaBean的约定:
1. set/get方法名遵守首字母大写,与属性名相同
2. javaBean 类为public, 必须要公共的无参构造器。
3. 属性为private
4. 属性必须通过set/get方法访问
5. 属性为 例如“URL”时,方法名setURL

2.1 常量注入
<property name="message" value="Hello"/>
<property name="index"><value>1</value></property>

value是个字符串,Spring容器会将value的字符串自动转化为属性类型。若转化出错抛出异常。
Spring对Boolean做了容错
true/false等于1/0等于yes/no等于on/off

2.2 注入集合类型(Set/List)
2.2.1 list

设置配置文件:

<?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:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

    <!-- 使用Setter方式注入-->
    <bean name="setterlist" class="com.myspring.helloworld.HelloSetterList"> 
    <!--指定构造器的参数-->
          <property name="values">
            <!--使用value-type设置list中的类型,
                默认value为String类型,
                也可以使用泛型如java.util.List<String> Spring容器自动识别泪表中的条目类型-->
            <list value-type="java.lang.String">  
              <value>1</value>
              <value>2</value>
              <value>3</value>
             </list>
         </property>
    </bean>
 </beans>

设置javaBean Class:

package com.myspring.helloworld;

import java.util.List;

public class HelloSetterList {

    private List<String> values;  
    public List<String> getValues() {  
        return values;  
    }  
    public void setValues(List<String> values) {  
        this.values = values;  
    }  
}  

设置测试类:

    BeanFactory beanFactory =  new ClassPathXmlApplicationContext("hellosetterlist.xml");  
    HelloSetterList listBean = beanFactory.getBean("setterlist", HelloSetterList.class);  
    System.out.println(listBean.getValues().size()); 
2.2.2 set

设置配置文件:

<?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:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

    <!-- 使用Setter方式注入-->
    <bean name="setterset" class="com.myspring.helloworld.HelloSetterSet"> 
    <!--指定构造器的参数-->
          <property name="values">
            <set>  
              <value>1</value>
              <value>2</value>
              <value>3</value>
             </set>
         </property>
    </bean>
 </beans>

设置java bean类:

package com.myspring.helloworld;

import java.util.Collection;

public class HelloSetterSet {

    private Collection<String> values;  
    public void setValues(Collection<String> values) {  
        this.values = values;  
    }  
    public Collection<String> getValues() {  
        return values;  
    }  
}

设置测试类:

    BeanFactory beanFactory =  
    new ClassPathXmlApplicationContext("hellosetterset.xml");  
          HelloSetterSet listBean = beanFactory.getBean("setterset", HelloSetterSet.class);  
    System.out.println(listBean.getValues().size()); 
2.3 注入数组类型

类似于list
只是将 “list” 转化为 “array”

2.4 注入Map类型

只是将 “list” 转化为 “map”
属性类型需要使用key-type 与 value-type标签
使用 key 与 value标签制定键对应的值数据。外围用 entry标签标记。

2.5 注入Properties类型

只是将 “list” 转化为 “props”
使用 key 与 value标签制定键对应的值数据。外围用 prop标签标记。

2.6 引用其他Bean注入
2.6.1 注入依赖Bean
  • 构造器方式
    这里写图片描述

    这里写图片描述

  • Setter方式

    这里写图片描述

    这里写图片描述
    具体实现:
    首先创建HelloApi实现类和HelloApiDecorator装饰类
    HelloApiDecorator装饰类:

 public class HelloApiDecorator implements HelloApi {  
private HelloApi helloApi;  
//空参构造器  
    public HelloApiDecorator() {  
}  
//有参构造器  
    public HelloApiDecorator(HelloApi helloApi) {  
        this.helloApi = helloApi;  
}    
public void setHelloApi(HelloApi helloApi) {  
        this.helloApi = helloApi;  
    }  
    @Override  
    public void sayHello() {  
        System.out.println("==========装饰一下===========");  
        helloApi.sayHello();  
        System.out.println("==========装饰一下===========");  
    }  
}

创建配置文件:

<!-- 定义依赖Bean, HelloImpl类, HelloApi的实现类-->  
<bean id="helloApi" class="com.myspring.helloworld.HelloImpl"/>  
<!-- 通过构造器注入 -->  
<bean id="bean1" class="com.myspring.helloworld.HelloApiDecorator">  
<constructor-arg index="0" ref="helloApi"/>  
</bean>  
<!-- 通过Setter注入 -->  
<bean id="bean2" class="com.myspring.helloworld.HelloApiDecorator">  
    <property name="helloApi"><ref bean="helloApi"/></property>  
</bean>
  • ref local 与 ref parent配置方式

    ref local 只能引用 id = “XXX”的方式,不能使用 name = “XXX”
    这里写图片描述
    ref parent 引用其他配置(官称父类)文件中的bean, 父类的bean名可以和本文件中的bean名重复。
    这里写图片描述
    具体实现:
    父类配置文件, 一定要用id:

    <!-- id 表示你这个组件的名字,class表示组件类-->  
    <!-- 使用默认的构造器-->
    <bean name="default_constructor" class="com.myspring.helloworld.HelloConstrustor"> </bean>  

    <!-- 使用带参数的构造器,父类属性需要使用id-->
    <bean id="argu_constructor" class="com.myspring.helloworld.HelloConstrustor"> 
    <!--指定构造器的参数-->
          <constructor-arg index="0" value = "hello argu construstor"/>  
    </bean> 

子类的配置文件,包含ref local 和 ref parent引用:


    <!-- 定义local的bean, 可以与父类同名-->
    <bean id="argu_constructor" class="com.myspring.helloworld.HelloConstrustor"> 
    <!--指定构造器的参数-->
          <constructor-arg index="0" value = "hello local argu construstor"/>  
    </bean>

    <!-- 通过local注入,使用id注入 -->  
    <bean id="local" class="com.myspring.helloworld.HelloApiDecorator">  
    <constructor-arg index="0"><ref local="argu_constructor"/></constructor-arg>  
    </bean>  
    <!-- 通过parent注入 -->  
    <bean id="parent" class="com.myspring.helloworld.HelloApiDecorator">  
    <property name="helloApi"><ref parent="argu_constructor"/></property>  
    </bean>

测试类:

        //初始化父容器  
        ApplicationContext parentBeanContext =  
        new ClassPathXmlApplicationContext("helloconstructor.xml");  
        //初始化当前容器  
        ApplicationContext beanContext = new ClassPathXmlApplicationContext(  
        new String[] {"helloref.xml"}, parentBeanContext);  
            HelloApi bean1 = beanContext.getBean("local", HelloApi.class);  
            bean1.sayHelo();//该Bean引用local bean  
        HelloApi bean2 = beanContext.getBean("parent", HelloApi.class);  
        bean2.sayHelo();//该Bean引用parent bean 
2.7 内部bean

内部bean对外部不可见。不能使用别名。

<bean id="bean" class="com.myspring.helloworld.HelloApiDecorator">  
<property name="helloApi">  
<bean id="helloApi" class="com.myspring.helloworld.HelloImpl"/>  
</property>  
</bean> 

装饰工厂真是个好东西,面向接口编程。方便。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值