欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringIOC学习_属性注入(依赖注入)

程序员文章站 2022-07-05 10:56:45
一、应用场景:Spring会帮创建实现类的实例,但是有时候我们还需要在类中设置一些属性用于传入设置值,这些跟类紧密关联的属性就叫依赖,通过spring帮忙设置的过程叫依赖注入。 二、依赖注入的实现 A.构造方法的注入。 通过上面无参构造我们想到是否有有参构造创建实例了,这样不就达到了注入属性的目的了 ......

一、应用场景:spring会帮创建实现类的实例,但是有时候我们还需要在类中设置一些属性用于传入设置值,这些跟类紧密关联的属性就叫依赖,通过spring帮忙设置的过程叫依赖注入。

二、依赖注入的实现

 a.构造方法的注入。

//这样配置bean都是通过无参构造生成bean实例
  <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl"/>

通过上面无参构造我们想到是否有有参构造创建实例了,这样不就达到了注入属性的目的了吗?确实,看下面:

//java代码:
private string name;
    public userdaoimpl(string name) {
        this.name = name;
    }
    @override
    public void insert() {
        
        system.out.println(name+"用户信息插入");
    }

//配置文件
     <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl">
            <constructor-arg name="name" value="李四"/>
        </bean>

只提供了有参构造而没有提供无参,所以现在spring只能通过有参构造来创建实例,并注入属性。

b.set方式注入。

  这种方式就比较常见了,在需要实例化的类里面提供属性及其set方法。

//java类里面:
private string name;
    
    @override
    public void insert() {
        
        system.out.println(name+"用户信息插入");
    }

    public void setname(string name) {
        this.name = name;
    }

配置文件里:

 <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl">
    <!-- 属性依赖注入,底层会自动封装,只要在dao实现类提供属性和set方法就行 -->
        <property name="name" value="张三"></property>
    </bean>

运行结果:

18:05:18,439  info classpathxmlapplicationcontext:578 - refreshing org.springframework.context.support.classpathxmlapplicationcontext@61443d8f: startup date [sun may 05 18:05:18 cst 2019]; root of context hierarchy
18:05:18,461  info xmlbeandefinitionreader:317 - loading xml bean definitions from class path resource [config/applicationcontext.xml]
张三用户信息插入

c.构造或者set设置非普通属性(对象或者数组等引用类型)

//在需要spring代理的实体类中用set或者构造
    private car car;
    
    /*public userdaoimpl(car car) {
        this.car = car;
    }*/
    
    public void setcar(car car) {
        this.car = car;
    }

    @override
    public void insert() {
    
        system.out.println(car);
    }
    

主要看配置文件:

      <bean id="car" class="cn.xxx.bean.car">
        <property name="carname" value="奇瑞qq"></property>
        <property name="money" value="50000"></property>
    </bean>
     
    <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl">
        <!-- <constructor-arg name="car" ref="car"></constructor-arg> -->
        <!-- 非普通属性注入,注意,ref为引用其他代理类的id或者name,这里面name里面car代表上面引用id的实例,必须保持一致,否则出错 -->
        <property name="car" ref="car"></property>
    </bean>

也就是说只靠在实体类里设置property不够,我们需要对象里面每个属性的值,所以直接把bean类托管给spring。在我们需要的类里面用ref属性引入这个bean类

运行结果:

18:43:10,444 info classpathxmlapplicationcontext:578 - refreshing org.springframework.context.support.classpathxmlapplicationcontext@61443d8f: startup date [sun may 05 18:43:10 cst 2019]; root of context hierarchy
18:43:10,476 info xmlbeandefinitionreader:317 - loading xml bean definitions from class path resource [config/applicationcontext.xml]
car [carname=奇瑞qq, money=50000.0]

 

d.p名称空间的属性注入(spring2.5版本以后)

  有点类似与表达式那种,可以替换一些标签,用处不大,了解一下。首先得引入p名称空间(名称空间是xml中的概念)

<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"    
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="car" class="cn.xxx.bean.car" p:carname="劳斯莱斯" p:money="12000000">
    </bean>
     
    <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl" p:car-ref="car" p:name="王校长">    
    </bean>
    

就是将一些在property等标签里面写的东西拿到了bean标签上面写,简化了代码量

 

e:spel的方式属性注入(spring3.x版本后使用)

  spel:spring expression language(spring表达式语言),语法:#{spel}

 

  <bean id="car" class="cn.xxx.bean.car" >
        <property name="carname" value="#{'奔驰'}" ></property>
        <property name="money" value="#{600000}"></property>
    </bean>
     
    <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl" >
        <!-- 注意不管数据类型复杂与否,都用value -->
        <property name="car" value="#{car}"></property>
        <!-- 引入另一个类里面的属性 -->
        <!-- <property name="carname" value="#{car.carname}"></property> -->

运行:

20:43:14,694  info classpathxmlapplicationcontext:578 - refreshing org.springframework.context.support.classpathxmlapplicationcontext@61443d8f: startup date [sun may 05 20:43:14 cst 2019]; root of context hierarchy
20:43:14,709  info xmlbeandefinitionreader:317 - loading xml bean definitions from class path resource [config/applicationcontext.xml]
car [carname=奔驰, money=600000.0]
小周用户信息插入

f:复杂数据类型注入(集合,数组)

配置文件:

 <bean id="userdao" class="cn.xxx.dao.impl.userdaoimpl" >
        <property name="arrs">
            <array>
                <value>你</value>
                <value>我</value>
                <value>它</value>
            </array>
        </property>
        
        <!-- 定义list集合 -->
        <property name="list">
            <list>
                <value>芙蓉</value>
                <value>如花</value>
                <value>凤姐</value>
            </list>
        </property>
        
        <!-- 定义map集合 ,key里面有个key-ref,所以可以传引入类型-->
        <property name="map">
            <map>
                <entry key="aaa" value="111"></entry>
                <entry key="bbb" value="222"></entry>
                <entry key="ccc" value="333"></entry>
            </map>
        </property>
    </bean>
//bean里面
private string[] arrs;
    private list<string> list;
    private map<string,string> map;public void setarrs(string[] arrs) {
        this.arrs = arrs;
    }

    public void setlist(list<string> list) {
        this.list = list;
    }

    public void setmap(map<string, string> map) {
        this.map = map;
    }

运行结果:

21:27:48,113  info classpathxmlapplicationcontext:578 - refreshing org.springframework.context.support.classpathxmlapplicationcontext@61443d8f: startup date [sun may 05 21:27:48 cst 2019]; root of context hierarchy
21:27:48,128  info xmlbeandefinitionreader:317 - loading xml bean definitions from class path resource [config/applicationcontext.xml]
你
我
它
芙蓉
如花
凤姐
aaa...111
bbb...222
ccc...333

如果是set集合那么就用set标签。上面就是属性注入全方位讲解了。