2.spring IOC(DI)

1. IOC(DI) - 控制反转(依赖注入)java

       所谓的IOC称之为控制反转,简单来讲就是将对象的建立的权利及对象的生命周期的管理过程交由Spring框架来处理,今后在开发过程当中再也不须要关注对象的建立和生命周期的管理,而是在须要时由Spring框架提供,这个由spring框架管理对象建立和生命周期的机制称之为控制反转。简单来讲就是原来是咱们本身在各层建立其余层的对象和销毁对象,容易形成程序层与层之间的耦合,如今spring容器帮咱们建立和管理对象,在咱们要使用的时候给咱们。 而在 建立对象的过程当中Spring能够依据配置对对象的属性进行设置,这个过称之为依赖注入,也即DI。web

      

2. IOC的入门案例spring

       a. 下载Springexpress

              访问Spring官网,下载Spring相关的包app

       b. 解压下载好的压缩包框架

              其中包含着Spring的依赖包dom

       c. 建立一个java项目ide

              spring并非非要在javaweb环境下才可使用,一个普通的java程序中也可使用Spring。测试

       d. 导入Spring的libs目录下IOC相关的jar包this

             

 

       beans是一种根标签

       context是上下文

    core是核心包包括了c3p0链接池

   expression是表达式

       a. 建立Spring的配置文件

              Spring采用xml文件做为配置文件,xml文件名字任意,但一般都取名为applicationContext.xml,一般将该文件放置在类加载的目录里下(src目录),方便后续使用。

建立bean类,并在spring中进行配置交由spring来管理

            1     <?xml version="1.0" encoding="UTF-8"?>
            2     <beans xmlns="http://www.springframework.org/schema/beans" 
            3             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            4             xsi:schemaLocation="http://www.springframework.org/schema/beans 
            5             http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
            6             
            7             <bean id="person" class="domain.Person"></bean>
            8             
            9     </beans>
<bean id="person" class="domain.Person"></bean>  
1.beanBean理解为类的代理或代言人(实际上确实是经过反射、代理来实现的),这样它就能表明类拥有该拥有的东西了,
2.id表明用于区分bean不可重复
3.class后面的domain.Person是咱们经过class.forname(.class)方法反射时须要的参数,forname方法的参数是包名+类名

在程序中经过Spring容器获取对象并使用

.java文件

package cn.tedu.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.tedu.domain.Person;

public class Test01 {
    
    /**
     * Spring中不能够配置多个id相同的bean,在容器初始化时会抛出异常
     */
    @Test
    public void test(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        Person p2 = (Person) context.getBean("person2");
        p.say();
System.out.println(p1); System.out.println(p2); } 

/** * 1.能够配置多个id不一样但类型相同(即反射指向的类是同一个)的bean,spring内存储的是不一样的对象
* 2.默认状况下屡次获取同一个id的bean获得的是同一个对象

**/
}

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-3.2.xsd ">
    <bean id="person" class="cn.tedu.domain.Person"></bean>
    <bean id="person2" class="cn.tedu.domain.Person"></bean>
</beans>
 

3. IOC的实现原理

       在初始化一个Spring容器时,Spring会去解析指定的xml文件,当解析到其中的<bean>标签时,会根据该标签中的class属性指定的类的全路径名,经过反射建立该类的对象,并将该对象存入内置的Map中管理。其中键就是该标签的id值,值就是该对象。

       以后,当经过getBean方法来从容器中获取对象时,其实就是根据传入的条件在内置的Map中寻找是否有匹配的键值,若是有则将该键值对中保存的对象返回,若是没有匹配到则抛出异常。

      

       由此能够推测而知:

              默认状况下,屡次获取同一个id的bean,获得的将是同一个对象。

              即便 是同一个类,若是配置过多个<bean>标签具备不一样的id,每一个id都会在内置Map中有一个键值对,其中的值是这个类建立的不一样的对象

              同一个<beans>标签下不容许配置多个同id的<bean>标签,若是配置则启动抛异常

 
经过反射建立对象

 

4. IOC获取对象的方式

 

       经过context.getBeans()方法获取bean时,能够经过以下两种方式获取:

 

              传入id值           context.getBeans("person");

 

              传入class类型  context.getBeans("Person.class");

 

       经过class方式获取bean时,若是同一个类配置过多个bean,则在获取时由于没法肯定到底要获取哪一个bean会抛出异常。

 

     而id是惟一的,不存在这样的问题,因此建议你们尽可能使用id获取bean。

 
        1     @Test
        2     /**
        3      * SpringIOC获取bean的方式
        4      */
        5     public void  test3(){
        6             /*
        7              <bean id="person" class="cn.tedu.beans.Person"></bean>
        8              */
        9             /*
       10              <bean id="person" class="cn.tedu.beans.Person"></bean>
       11              <bean id="personx" class="cn.tedu.beans.Person"></bean>
       12              */
       13             ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       14             //--经过id获取
       15             Person p1 = (Person) context.getBean("person");
       16             p1.say();
       17             //--经过class获取
       18             Person p2 = context.getBean(Person.class);
       19             p2.say();
       20     }
 

5. 别名标签

       在 Spring中提供了别名标签<alias>能够为配置的<bean>起一个别名,要注意的是这仅仅是对指定的<bean>起的一个额外的名字,并不会额外的建立对象存入map。原来的id仍是能够用

              <alias name="要起别名的bean的id"  alias="要指定的别名"/>

 
@Test
/**
 * SpringIOC中bean别名
 */
public void  test4(){
        /*
                <bean id="person" class="cn.tedu.beans.Person"></bean>
                <alias name="person" alias="personx"/>        
         */
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //--经过id获取
        Person p1 = (Person) context.getBean("personx");
        p1.say();
}
 

6. Spring建立对象的方式

       a. 经过类的没法构造方法建立对象

              在入门案例中使用的就是这种方式。当用最普通方式配置一个<bean>时,默认就是采用类的无参构造建立对象。在Spring容器初始化时,经过<bean>上配置的class属性反射获得字节码对象,经过newInstance()建立对象

         

                   Class c = Class .forName("类的全路径名称")
                   Object obj = c.newInstance()

 

              这种方式下spring建立对象,要求类必须有无参的构造,不然没法经过反射建立对象,会抛出异常。

                      

package cn.tedu.beans;

public class Person {
    public Person(String arg) {
        System.out.println("Person的无参构造执行了。。。");
    }
    public void say(){
        System.out.println("person hello spring~");
    }
}

/**
* 若是bean不存在无参构造 ,则经过默认反射方式没法建立对象,Spring容器初始化时会抛出异常
* <bean id="person" class="cn.tedu.domain.Person"/>
*/
@Test
public void test01(){
//1.初始化Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.基于Spring容器建立对象
Person p1 = (Person) context.getBean("person");
//3.测试
System.out.println(p1);

 

会引起异常

 

       b. 经过静态工厂建立对象

             不少的时候,咱们面对的类是没法经过无参构造去建立的,例如该类没有无参构造、是一抽象类 等等状况 ,此时没法要求spring经过无参构造建立对象,此时可使用静态工厂 方式建立对象。

             

package cn.tedu.factory;

import cn.tedu.domain.Person;

public class PersonStaticFactory {
    public static Person getPerson(){
        Person p = new Person("zs");
        return p;
    }
}

测试

    /**
     * 静态工厂
       <bean id="person" 
        class="cn.tedu.factory.PersonStaticFactory" 
        factory-method="getPerson"/>       factory-method 指明获取到对象的方法
     */
    @Test
    public void test02(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.获取bean
        Person p = (Person) context.getBean("person");
        //3.测试
        p.eat();
        p.say();
    }

配置文件

<bean id="person" class="cn.tedu.factory.PersonStaticFactory" factory-method="getPerson"/> 

 

       c. 实例工厂建立对象

              实例工厂也能够解决类是没法经过无参构造建立的问题,解决的思路和静态 工厂相似,只不过实例工厂提供的方法不是静态的。spring须要先建立出实例工厂的对象,在调用实例工厂对象上指定的普通方法来建立对象。因此实例工厂也须要配置到Spring中管理。

       

package cn.tedu.factory;

import cn.tedu.domain.Person;

public class PersonInstanceFactory {
    public Person getPerson(){
        Person p = new Person("zs");
        return p;
    }
}
    @Test
    public void test03(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.获取bean
        Person p = (Person) context.getBean("person");
        //3.测试
        p.eat();
        p.say();
    }

配置文件

<bean id="pifactory" class="cn.tedu.factory.PersonInstanceFactory"  />     //先建立一个工厂类对象,经过对象调用里面的非静态方法
    <bean id="person" factory-bean="pifactory" factory-method="getPerson"/>  //要建立的对象,factory-bean 指代的是采用哪一个工厂类对象,factory-method 对象调用的方法
 

 

       d. Spring工厂建立对象

              Spring内置了工厂接口,也能够经过实现这个接口来开发Spring工厂,经过这个工厂建立对象。

package cn.tedu.factory;

import org.springframework.beans.factory.FactoryBean;

import cn.tedu.domain.Person;

public class PersonSpringFactory implements FactoryBean<Person> { //首先要实现FactoryBean接口 里面的泛型规定的是实际产生的对象

    /**
     * 获取bean
     */
    public Person getObject() throws Exception {
        return new Person("zs");
    }

    /**
     * 获取bean的类型
     */
    public Class<?> getObjectType() {
        return Person.class;
    }

    /**
     * 肯定对象是不是单例的
     */
    public boolean isSingleton() {
        return true;
    }

}
    @Test
    public void test04(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.获取bean
        Person p = (Person) context.getBean("person"); //返回的是object类型
        //3.测试
        p.eat();
        p.say();
    }
<bean id="person" class="cn.tedu.factory.PersonSpringFactory"/>

 

               

7. 单例和多例

       Spring容器管理的bean在默认状况下是单例的,也即,一个bean只会建立一个对象,存在内置 map中,以后不管获取多少次该bean,都返回同一个对象。

       Spring默认采用单例方式,减小了对象的建立,从而减小了内存的消耗。

       可是在实际开发中是存在多例的需求的,Spring也提供了选项能够将bean设置为多例模式。

    

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    
    /**
     * Spring容器默认 单例 方式管理bean
     * 能够经过配置bean的scope属性来控制 单例/多例
        <!-- 
        bean的scope属性:
            singleton:单例方式管理bean,默认就是单例
            prototype:多例方式管理bean
        -->
        <bean id="person" class="cn.tedu.domain.Person" scope="prototype"/>
     */
    @Test
    public void test01(){
        //1.初始化Spring容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        Person p2 = (Person) context.getBean("person");
        //3.测试
        System.out.println(p1); //单例的话地址值一致,多例不一致
        System.out.println(p2);
    }
    
}

配置文件

<?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-3.2.xsd ">
    
    <!-- 
        bean的scope属性:
            singleton:单例方式管理bean,默认就是单例
            prototype:多例方式管理bean
     -->
    <bean id="person" class="cn.tedu.domain.Person" scope="prototype"/>
</beans>

       bean在单例模式下的生命周期:

              bean在单例模式下,spring容器启动时解析xml发现该bean标签后,直接建立该bean的对象存入内部map中保存,此后不管调用多少次getBean()获取该bean都是从map中获取该对象返回,一直是一个对象。此对象一直被Spring容器持有,直到容器退出时,随着容器的退出对象被销毁。

      

       bean在多例模式下的生命周期:

              bean在多例模式下,spring容器启动时解析xml发现该bean标签后,只是将该bean进行管理,并不会建立对象,此后每次使用 getBean()获取该bean时,spring都会从新建立该对象返回,每次都是一个新的对象。这个对象spring容器并不会持有,什么销毁取决于使用该对象的用户本身何时销毁该对象。

 

8. 懒加载机制

       Spring默认会在容器初始化的过程当中,解析xml,并将单例的bean建立并保存到map中,这样的机制在bean比较少时问题不大,但一旦bean很是多时,spring须要在启动的过程当中花费大量的时间来建立bean 花费大量的空间存储bean,但这些bean可能好久都用不上,这种在启动时在时间和空间上的浪费显得很是的不值得。

       因此Spring提供了懒加载机制。所谓的懒加载机制就是能够规定指定的bean不在启动时当即建立,而是在后续第一次用到时才建立并将对象放入map中,从而减轻在启动过程当中对时间和内存的消耗。

       懒加载机制只对单例bean有做用,对于多例bean设置懒加载没有意义。

      

       懒加载的配置方式:    

<?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-3.2.xsd "
    default-lazy-init="true" //为全局bean配置懒加载机制
    >
    <bean id="person" class="cn.tedu.domain.Person" lazy-init="true"/> //   为指定bean配置懒加载
</beans>

              **若是同时设定全局和指定bean的懒加载机制,且配置不相同,则对于该bean局部配置覆盖全局配置。           

9. 配置初始化和销毁的方法

       在Spring中若是某个bean在初始化以后 或 销毁以前要作一些 额外操做能够为该bean配置初始化和销毁的方法 ,在这些方法中完成要功能。

      

public class Person{
    public Person() {
        System.out.println("Person建立了..");
    }
    public void personInit(){
        System.out.println("初始化Person...");
    }
    public void personDestory(){
        System.out.println("销毁Person...");
    }
    public void eat(){
        System.out.println("吃...");
    }
    public void say(){
        System.out.println("说...");
    }
}

 

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    
    /**
     * 初始化 和 销毁 方法
     */
    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        //3.测试
        System.out.println(p1);
        //4.关闭容器
        context.close(); //ApplicationContext接口没有close方法,他的实现类    ClassPathXmlApplicationContext 有这个方法
    }
    
}

配置文件

  

<?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-3.2.xsd "
    >
    
    <bean id="person" class="cn.tedu.domain.Person"
        init-method="personInit"           //对象初始化的方法
        destroy-method="personDestory"       //对象销毁时的方法
    />
    
</beans>

    **Spring中关键方法的执行顺序:

              在Spring建立bean对象时,先建立对象(经过无参构造或工厂),以后当即调用init方法来执行初始化操做,以后此bean就能够哪来调用其它普通方法,而在对象销毁以前,spring容器调用其destory方法来执行销毁操做。

二。DI 依赖注入

 

1. IOC(DI) - 控制反转(依赖注入)

       所谓的IOC称之为控制反转,简单来讲就是将对象的建立的权利及对象的生命周期的管理过程交由Spring框架来处理,今后在开发过程当中再也不须要关注对象的建立和生命周期的管理,而是在须要时由Spring框架提供,这个由spring框架管理对象建立和生命周期的机制称之为控制反转。而在 建立对象的过程当中Spring能够依据配置对对象的属性进行设置,这个过称之为依赖注入,也即DI。

2. set方法注入

       一般的javabean属性都会私有化,而对外暴露setXxx()getXxx()方法,此时spring能够经过这样的setXxx()方法将属性的值注入对象。 

      

       a. Spring普通属性注入:

首先是Person javaBean类
package cn.tedu.domain;

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


public class Person{
    private int id;
    private String name;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties prop;
    private Dog dog;  //属性中包含其余对象 private Cat cat;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Set<String> getSet() {
        return set;
    }
    public void setSet(Set<String> set) {
        this.set = set;
    }
    public Map<String, String> getMap() {
        return map;
    }
    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    public Properties getProp() {
        return prop;
    }
    public void setProp(Properties prop) {
        this.prop = prop;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    
    public Cat getCat() {
        return cat;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + ", list=" + list
                + ", set=" + set + ", map=" + map + ", prop=" + prop + ", dog="
                + dog + ", cat=" + cat + "]";
    }
}
 

Dog类 和Cat类

package cn.tedu.domain;

public class Dog {
    private String name;
    private int age;
    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;
    }
    @Override
    public String toString() {
        return "Dog [name=" + name + ", age=" + age + "]";
    }
}
package cn.tedu.domain;

public class Cat {
    private String name;
    private int age;
    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;
    }
    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age + "]";
    }
}

 

配置文件中的属性注入

<?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-3.2.xsd "
    >
    
    <bean id="person" class="cn.tedu.domain.Person">
        <property name="id" value="99"></property>
        <property name="name" value="亚瑟"></property>
        <property name="list">
            <list>
                <value>上单</value>
                <value>下单</value>
                <value>打野</value>
                <value>中单</value>
                <value>辅助</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>s1</value>
                <value>s2</value>
                <value>s3</value>
                <value>s2</value>
                <value>s4</value>
                <value>s5</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="k1" value="v1"></entry>
                <entry key="k2" value="v2"></entry>
                <entry key="k3" value="v3"></entry>
                <entry key="k2" value="v22"></entry>
            </map>
        </property>
        <property name="prop">
            <props>
                <prop key="p1">v1</prop>
                <prop key="p2">v2</prop>
                <prop key="p3">v3</prop>
            </props>
        </property>
        <property name="dog" ref="dog"></property>   
        <property name="cat" ref="cat"></property>
    </bean>
    <bean id="dog" class="cn.tedu.domain.Dog">
        <property name="name" value="旺财"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="cat" class="cn.tedu.domain.Cat">
        <property name="name" value="汤姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

要先建立属性对象的bean。

在这里要申明一点的是:<property name="age" value="5"></property>  中name的值即age,这是一个javaBean属性即Person javabean中SetXxx()方法的后三个单词xxx,而不是Person中的age成员属性,就好比把age的setAge(int age)方法改为

setAgebbb(int age) ,那么要改为<property name="agebbb" value="5"></property>

    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        //3.测试
        System.out.println(p1);
        //4.关闭容器
        context.close();
    }
    
 

自动装配---支持的是bean对象的注入

 

       在Spring的set方式实现的注入过程当中,支持自动装配机制,所谓自动装配机制,会根据要设置的javabean属性的名字 或 类型 到spring中自动寻找对应id 或 类型的<bean>进行设置,从而 省去依次配置的过程,简化了配置。

 

       为 指定<bean>开启自动装配:

<?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-3.2.xsd "
    default-autowire="byName"  全局自动装配
> <!-- autowire自动装配: byName: 根据要注入的属性名寻找同id的bean进行注入 若是找不到不报错也不注入 byType: 根据要注入的属性类型寻找同类型的bean进行注入 若是存在多个该类型的bean则报错

   **byType方式 根据类型进行匹配,可能匹配到多个<bean>,此时会抛出异常。而byName是经过id来寻找<bean>,id没有重复,不会有这方面的问题,因此推荐使用byName方式

-->
    <bean id="person" class="cn.tedu.domain.Person" autowire="byType">  局部自动装配
        <!-- 
        <property name="dog" ref="dog"></property>
        <property name="cat" ref="cat"></property> 
        -->
    </bean>
    <bean id="dogx" class="cn.tedu.domain.Dog">
        <property name="name" value="旺财"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="catx" class="cn.tedu.domain.Cat">
        <property name="name" value="汤姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

 Person类  

package cn.tedu.domain;

public class Person{
    private Dog dog;
    private Cat cat;
    
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    public Cat getCat() {
        return cat;
    }
    public void setCat(Cat cat) {
        this.cat = cat;
    }
    @Override
    public String toString() {
        return "Person [dog=" + dog + ", cat=" + cat + "]";
    }
    
}

测试

public class Test01 {
    public static void main(String[] args) {
        new Test01().test01();
    }
    
    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        //3.测试
        System.out.println(p1);
        //4.关闭容器
        context.close();
    }
    
}

4. 基于构造方法的注入

     对象属性设置的另外一种方式是在对象建立的过程当中经过构造方法传入并设置对象的属性。spring也能够经过这样的构造方法实现属性的注入

 测试

    @Test
    public void test01(){
        //1.初始化Spring容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.基于Spring容器建立对象 
        Person p1 = (Person) context.getBean("person");
        //3.测试
        System.out.println(p1);
        //4.关闭容器
        context.close();
    }
<?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-3.2.xsd "
    >
    <bean id="person" class="cn.tedu.domain.Person">
        <!--
            构造方法方式实现属性注入:
                经过<constructor-arg>能够实现bean的构造方法方式实现注入
                其中的属性:
                    name:限定要为哪一个名字的构造方法参数注入
                    index: 为哪一个索引位的构造方法参数注入
                    type: 当前注入的参数的类型
                    value: 要为当前参数设定什么值,若是是非自定义bean类型,使用此属性注入
                    ref: 要为当前参数设定哪一个自定义bean,若是是自定义bean类型,使用此属性注入
        
        -->
        <!-- 
        <constructor-arg name="name" value="zs"></constructor-arg>
        <constructor-arg name="age" value="19"></constructor-arg>
         -->
         <constructor-arg index="0"  value="zs"></constructor-arg>
         <constructor-arg index="1"  value="19"></constructor-arg>
         <constructor-arg index="2" ref="dog"></constructor-arg>
         <constructor-arg index="3" ref="cat"></constructor-arg>
    </bean>
    <bean id="dog" class="cn.tedu.domain.Dog">
        <property name="name" value="旺财"></property>
        <property name="age" value="6"></property>
    </bean>
    <bean id="cat" class="cn.tedu.domain.Cat">
        <property name="name" value="汤姆"></property>
        <property name="age" value="5"></property>
    </bean>
</beans>

一般使用index进行参数注入,由于你一般用的是别人的jar包,没有源代码的状况下,你只能知道参数的个数,以及参数的类型,没法得到参数名。因此这就致使了有些方法你调用的时候参数部分是arg0,arg1,arg2

相关文章
相关标签/搜索