加载IOC容器的配置文件

一般我们都是用的ClassPathXmlApplicationContext,见名知意,加载在类路径下的配置文件,此外,我们还可以使用FileSystemXmlApplicationContext,来加载磁盘中的配置文件。

超详细的Spring使用_spring

使用,在配置文件中注册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.xsd">

  <!--一个bean标签可以注册一个组件(类、对象)-->
        <bean id="person" class="com.luo.spring.bean.Person"> </bean>
</beans>

问题一:什么时候IOC创建了对象呢,加载配置文件时,还是在需要使用时加载?

  @Test
    public void test01() {
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
    }
    
public class Person {
    public Person() {
        System.out.println("创建了对象");
    }
}

输出试试

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.luo.spring.test.SpringTest,test01
创建了对象

Process finished with exit code 0

可见,在创建IOC容器时就创建了对象

问题二:两次获取同一个bean,是否是同一个对象呢?

  @Test
    public void test02(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        //根据id获取bean
        Object person1 = applicationContext.getBean("person");
        Object person2 = applicationContext.getBean("person");
        System.out.println(person1==person2);
    }
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=61184:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit-bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.luo.spring.test.SpringTest,test02
创建了对象
true

Process finished with exit code 0

是同一个对象,可知 IOC容器中的bean默认是单例的

问题三: IOC容器是什么时候以及怎么进行对象赋值的?

	@Test
    public void test02(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        //根据id获取bean
        Object person1 = applicationContext.getBean("person");
    }
<?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标签可以注册一个组件(类、对象)-->
<bean id="person" class="com.luo.spring.bean.Person">
    <!--bean的属性以及属性值-->
    <property name="name" value="luo"></property>
    <property name="age" value="12"></property>
</bean>

</beans>
public class Person {
   public String name;
    private Integer age;

    public Person() {
        System.out.println("创建了对象");
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("setname = "+name);
    }
    public void setAge(Integer age) {
        this.age = age;
        System.out.println("setage = "+age);
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

输出结果如下

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=61251:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar;D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit-bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar" 
创建了对象
setname = luo
setage = 12

Process finished with exit code 0

由结果可知,在创建对象之后,如果bean有 property 属性就会利用setter方法对对象进行属性的赋值

问题四:JavaBean的属性名是由谁决定的?

//我把Javabean所在类的setName改成了setLName
public void setLName(String name) {
        this.name = name;
        System.out.println("setname = "+name);
    }

超详细的Spring使用_java_02
配置文件直接报错,可知,javabean的属性名是由setter决定的

问题五:通过class获取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.xsd">

<!--一个bean标签可以注册一个组件(类、对象)-->
<bean id="person" class="com.luo.spring.bean.Person"></bean>
<bean class="com.luo.spring.bean.Person"> </bean>
</beans>
@Test
    public void test01() {
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        Person person = applicationContext.getBean(Person.class);
        System.out.println(person);
    }

结果如下

"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=61522:D:\IntelliJ IDEA\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\IntelliJ IDEA\IntelliJ bin\rep\com\fasterxml\jackson\core\jackson-annotations\2.10.0\jackson-annotations-2.10.0.jar" 
创建了对象
创建了对象

org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.luo.spring.bean.Person' available: expected single matching bean but found 2: person,com.luo.spring.bean.Person#0

Process finished with exit code -1

报 NoUniqueBeanDefinitionException 异常,那么怎么解决呢,如下

  @Test
    public void test01() {
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
       //同时指定id和类型,可防止异常发生
        Person person = applicationContext.getBean("person",Person.class);
        System.out.println(person);
    }

上面说了对象属性的赋值,是利用的setter创建的,那么还有其他方法没有呢?答案是肯定有的。
下面是利用构造器进行对象的创建和赋值

<bean class="com.luo.spring.bean.Person">
        <!--调用有参构造方法进行对象的创建和赋值,有几个参数就写几个constructor-arg -->
        <constructor-arg name="name" value="luo"></constructor-arg>
        <constructor-arg name="age" value="12"></constructor-arg>
    </bean>
    <!--直接对构造器value赋值,默认必须类型顺序一致,如果顺序不一致,则指定下标index
        如果是重载,指定下标的同时还要指定其类型
    -->
    <bean class="com.luo.spring.bean.Person">
        <constructor-arg value="76" index="1" type="java.lang.Integer"></constructor-arg>
        <constructor-arg value="luo"></constructor-arg>
    </bean>

那还有么有呢?有的,P命名空间,用的较少,我就不举例啦。。。
哈哈