Spring入门第二课

Posted alittlecomputer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring入门第二课相关的知识,希望对你有一定的参考价值。

这次课我们详细理解一下Spring,理解每一行代码到底是什么意思。

我们在上次的代码上做一点修改:

Persion.java

 1 package com.study.entity;
 2 
 3 public class Persion {
 4     
 5     private String name;
 6     private Integer age;
 7     public String getName() {
 8         return name;
 9     }
10     public void setName(String name) {
11         System.out.println("setName:"+name);
12         this.name = name;
13     }
14     public Integer getAge() {
15         return age;
16     }
17     public void setAge(Integer age) {
18         this.age = age;
19     }
20     @Override
21     public String toString() {
22         return "Persion [name=" + name + ", age=" + age + "]";
23     }
24     public Persion(String name, Integer age) {
25         super();
26         this.name = name;
27         this.age = age;
28     }
29     public Persion() {
30         System.out.println("Persion\'s Contructor....");
31     }
32 }

我们在第10行和第30行加了打印。目的就是我想知道Persion是什么时候被创建了并且设置了属性。

我们在TestPersion中修改:

 1 package com.study.entity;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class TestPersion {
 7 
 8     public static void main(String[] args) {
 9 //        Persion p1 = new Persion();
10 //        p1.setName("xiaoming");
11 //        System.out.println(p1.getName());
12         
13         //1.创建Spring的IOC容器对象
14         System.out.println("开始创建Spring的IOC容器");
15         ApplicationContext ext = new ClassPathXmlApplicationContext("applicationContext.xml");
16         System.out.println("结束创建Spring的IOC容器");
17         
18         //2.从IOC容器中获取Bean实例
19         System.out.println("开始从IOC容器中获取Bean实例");
20         Persion p2 = (Persion) ext.getBean("persionService");
21         System.out.println("结束从IOC容器中获取Bean实例");
22         
23         //3.调用实例对象的方法
24         System.out.println("开始调用实例对象的方法");
25         System.out.println(p2.toString());
26         System.out.println("结束调用实例对象的方法");
27     }
28 
29 }

我们在之前代码的每一行前后都加了打印,目的就是想看看Spring创建对象的过程。

我们的applicationContext.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.xsd">
    <!-- 配置Bean
    class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有 无参的构造函数
    id:表示容器的bean,id是唯一的,即在这个xml文件中要唯一 -->
    <bean id="persionService" class="com.study.entity.Persion">
    <property name="name" value="xiaozhang"></property>
    </bean>
</beans>

 

输出的结果如下:

开始创建Spring的IOC容器
三月 05, 2020 8:28:51 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1dd92fe2: startup date [Thu Mar 05 20:28:51 CST 2020]; root of context hierarchy
三月 05, 2020 8:28:51 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Persion\'s Contructor....
setName:xiaozhang
结束创建Spring的IOC容器
开始从IOC容器中获取Bean实例
结束从IOC容器中获取Bean实例
开始调用实例对象的方法
Persion [name=xiaozhang, age=null]
结束调用实例对象的方法

可以看到,我们在创建Spring的IOC容器的时候,就会创建Persion的实例对象,并且给对象的属性赋值。

也就是说,只要容器启动了,容器内就已经存在xml中配置的实例对象,所以我们可以通过getBean的方式去获取Bean。

 

 我们讲一下IOC和DI。IOC(Inversion of Control):其思想是翻转资源获取的方向,传统的资源查找方式要求组件向容器发起请求查找资源。作为回应,容器适当的时候返回资源。而应用了IOC之后,则是容器主动的将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源。这种行为也被称为查找的被动形式。

DI(Dependency Injection)组件以一些预先定义好的方式(如setter方法)接受来自容器的资源注入。

 

 

package logan.spring.study;

public class HelloWorld {
    
    private String name;
    
    public void setName2(String name){
        System.out.println("setName: "+ name);
        this.name = name;
    }
    public void hello(){
        System.out.println("hello: " + name);
    }
    public HelloWorld(){
        System.out.println("HelloWorld\'s Constructor...");
    }

}
package logan.spring.study;

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

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.创建Spring的IOC容器对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从 IOC容器中获取Bean实例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
        //3.调用hello方法
        System.out.println(helloWorld);

    }

}

applicationContext

<?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
    class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>

</beans>

输出结果

五月 18, 2017 8:51:39 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3eb07fd3: startup date [Thu May 18 20:51:39 CST 2017]; root of context hierarchy
五月 18, 2017 8:51:39 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
HelloWorld\'s Constructor...
logan.spring.study.HelloWorld@48eff760

ApplicationContext本身是一个容器

ApplicationContext的主要实现类:

ClassPathXmlApplicationContext():从类路径下加载配置文件

FileSystemXmlApplicationContext:从文件系统加载配置文件

ConfigurableAppliactionContext扩展于ApplicationContext,新增加两个主要方法,refresh()和close(),让ApplicationContext具有启动,刷新和关闭上下文的功能。

ApplicationContext在初始化上下文时就实例化所有单例的Bean。

WebApplicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作。

获取bean还可以用一下方式:

package logan.spring.study;

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

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //1.创建Spring的IOC容器对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从 IOC容器中获取Bean实例
        HelloWorld helloWorld = (HelloWorld) ctx.getBean("hello");
        HelloWorld hello = ctx.getBean(HelloWorld.class);
        //3.调用hello方法
        System.out.println(hello);

    }

}

这样做有缺点,就是如果在配置文件里面配置两个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
    class:bean的全类名,通过反射的方式在IOC容器中创建bean,所以要求Bean中必须有无参的构造函数
    id:表示容器的bean,id唯一 -->
    <bean id="hello" class="logan.spring.study.HelloWorld">
    </bean>
    
    <bean id="hello2" class="logan.spring.study.HelloWorld">
    </bean>

</beans>

这样就会报错

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type \'logan.spring.study.HelloWorld\' available: expected single matching bean but found 2: hello,hello2
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1093)
    at logan.spring.study.Main.main(Main.java:14)

所以在利用类型返回IOC容器中的Bean,但是要求IOC容器中必须只能有一个该类型的Bean。

以上是关于Spring入门第二课的主要内容,如果未能解决你的问题,请参考以下文章

Spring入门第十二课

HTML(入门第二课)

python入门第二课

Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装

StoneDB Class入门第二课:StoneDB整体架构解析

StoneDB Class入门第二课:StoneDB整体架构解析