当一个类A作为类B的属性,如何实例化类A:
主动创建:

public class catService {
    //注入方式1:new对象
    catDao cd=new catDao();
}

非主动创建:

public class catService {
//注入方式2:参数传入
    private catDao cd;
    public  catService(catDao catDao){
        this.cd=catDao;
    }
}

对比第二种方式,并没有像第一种方式一样创建对象,而是通过带参方法的形式传入一个对象,从而实现依赖,而实际的对象创建交给了外部。

1:set注入(首选)

前提:需要提供属性的set方法

a:bean对象的注入

public class userDao {
    public void userDaoMethod(){
        System.out.println("userDaoMethod");
    }
}
public class userService {
    private dao.userDao userDao;
    //set方法注入业务对象
    public void setUserDao(dao.userDao userDao) {
        this.userDao = userDao;
    }
    public void userServiceMethod(){
        this.userDao.userDaoMethod();
    }
}
<!--
IOC通过property标签手动装配(注入)
  Set方法注入:
        name:bean对象中的属性名
        ref:指定bean标签的id属性值,将实例化好的userDao传给set方法
-->
<bean id="userDao" class="dao.userDao"></bean>

<bean id="userService" class="service.userService">
    <property name="userDao" ref="userDao"></property>
</bean>

b:基本引用和基本数据类型

<!--String-->
<property name="host" value="localHost"></property>
<!--Integer-->
<property name="port" value="8080"></property>
<!--list-->
<property name="list">
    <list>
        <value>上海</value>
        <value>北京</value>
    </list>
</property>
<!--map-->
<property name="map">
    <map>
        <entry>
            <key><value>1</value></key>
            <value>一号</value>
        </entry>
        <entry>
            <key><value>2</value></key>
            <value>二号</value>
        </entry>
    </map>
</property>
<!--properties-->
<property name="properties">
    <props>
        <prop key="jdbc.driver">com.mysql.jdbc.Driver</prop>
    </props>
</property>

P名称空间:

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

便于set注入的使用:

<!--set注入使用P名称空间-->
<bean id="pDap" class="dao.pDao"></bean>

<bean id="pService" class="service.pService" p:pd-ref="pDap" p:str="p名称空间">
</bean>

2:构造器注入

前提:提供带参的构造器

catDao作为catService的属性:

public class catService {
    private catDao cd;
        //提供带参构造
    public catService(catDao cd){
        this.cd=cd;
    }
    public void catServiceMethod(){
        System.out.println("catServiceMethod");
        this.cd.catDaoMethod();
    }
}
public class catDao {
    public void catDaoMethod(){
        System.out.println("catDaoMethod");
    }
}

spring.xml:

<!--
SpringIOC手动装配(注入):
        构造器注入:
        constructor-arg标签进行注入
        name:对应形参名
        ref:指定bean标签的id属性值
        value:值
        index:参数下标 从0开始
-->
<bean id="catDao" class="dao.catDao"></bean>

<bean id="catService" class="service.catService">
    <constructor-arg name="cd" ref="catDao"></constructor-arg>
</bean>

如果存在多个bena属性:

<bean id="catService" class="service.catService">
    <constructor-arg name="cd" ref="catDao"></constructor-arg>
    <constructor-arg name="ud" ref="userDao"></constructor-arg>
</bean>

构造器注入的问题:
如果A依赖B,B依赖A,都是构造器注入,则会引起循环依赖,通过set注入则会避免循环依赖。因为set注入在实例化对象时不需要注入属性,只有在使用时才会去注入属性。

3:静态工厂注入

静态工厂注入的本质:
利用set注入被静态工厂实例化的bean。

前提:set方法

TypeDao作为TypeService的属性:

//DAO
public class TypeDao {
    public void TypeDaoTest(){
        System.out.println("TypeDaoTest");
    }
}
//Service
public class TypeService {
    private TypeDao td;
    public void setTd(TypeDao td) {
        this.td = td;
    }
    public void TypeServiceTest(){
        System.out.println("TypeServiceTest");
    }
}

静态工厂类:

//factory
public class StaticFactory {
    //定义静态方法
    public static TypeDao createTypeDao(){
        return new TypeDao();
    }
}

spring.xml:

<!--
静态工厂注入:
            静态工厂注入也是借助set注入,被注入的bean对象是静态工厂实例化的
-->
<!--静态工厂实例化-->
<bean id="typeDao" class="factory.StaticFactory" factory-method="createTypeDao"></bean>

<!--引用静态工厂实例化的bean进行注入-->
<bean id="typeService" class="service.TypeService">
    <property name="td" ref="typeDao"></property>
</bean>

4:实例化工厂注入

实例化工厂注入的本质:
注入被实例化工厂实例的bean对象

实例化工厂类:

//实例化工厂
public class dynamicFactory {
    public TypeDao createTD(){
        return new TypeDao();
    }
}

spring.xml:

<!--
实例化工厂注入:
                实例化工厂注入,借助set注入被实例化工厂 实例化的bean对象
-->
<!--实例化工厂bean-->
<bean id="dynamicFactory" class="factory.dynamicFactory"></bean>

<!--通过实例化工厂 实例bean-->
<bean id="typeDao" factory-bean="dynamicFactory" factory-method="createTD"></bean>

<!--将通过实例化工厂 实例的bean 利用set注入-->
<bean id="typeService" class="service.TypeService">
    <property name="td" ref="typeDdao"></property>
</bean>