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

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

Persion.java

 package com.study.entity;

 public class Persion {

     private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("setName:"+name);
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Persion [name=" + name + ", age=" + age + "]";
}
public Persion(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Persion() {
System.out.println("Persion's Contructor....");
}
}

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

我们在TestPersion中修改:

 package com.study.entity;

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestPersion { public static void main(String[] args) {
// Persion p1 = new Persion();
// p1.setName("xiaoming");
// System.out.println(p1.getName()); //1.创建Spring的IOC容器对象
System.out.println("开始创建Spring的IOC容器");
ApplicationContext ext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("结束创建Spring的IOC容器"); //2.从IOC容器中获取Bean实例
System.out.println("开始从IOC容器中获取Bean实例");
Persion p2 = (Persion) ext.getBean("persionService");
System.out.println("结束从IOC容器中获取Bean实例"); //3.调用实例对象的方法
System.out.println("开始调用实例对象的方法");
System.out.println(p2.toString());
System.out.println("结束调用实例对象的方法");
} }

我们在之前代码的每一行前后都加了打印,目的就是想看看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入门第二课的更多相关文章

  1. Spring入门第二课:Spring配置Bean的细节

    1.配置bean的作用域: 通过配置scope属性可以bean的作用域,参数有 prototype.request.session.singleton. 1)singleton为单例,IoC容器只会创 ...

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

    Hibernate入门第二课 Hibernate Tools for Eclipse Plugins安装 你们可以直接去,http://blog.csdn.net/wei_chong_chong/ar ...

  3. 数据结构入门第二课(浙大mooc)

    数据结构入门第二课 目录 数据结构入门第二课 引子 多项式的表示 方法1 顺序结构表示多项式各项 方法2 顺序结构表示非零项 方法3 链表结构存储非零项 多项式问题的启示 线性表 线性表的抽象数据类型 ...

  4. Kotlin入门第二课:集合操作

    测试项目Github地址: KotlinForJava 前文传送: Kotlin入门第一课:从对比Java开始 初次尝试用Kotlin实现Android项目 1. 介绍 作为Kotlin入门的第二课, ...

  5. Spring入门第二十九课

    事务的隔离级别,回滚,只读,过期 当同一个应用程序或者不同应用程序中的多个事务在同一个数据集上并发执行时,可能会出现许多意外的问题. 并发事务所导致的问题可以分为下面三种类型: -脏读 -不可重复读 ...

  6. Spring入门第二十八课

    事务的传播行为 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,例如:方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务中运行. 事务的传播行为可以由传播属性指定.Spr ...

  7. Spring入门第二十七课

    声明式事务 直接上代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Dri ...

  8. Spring入门第二十六课

    Spring中的事务管理 事务简介 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性. 事务就是一系列的动作,他们被当做一个单独的工作单元,这些动作要么全部完成,要么全部不起 ...

  9. Spring入门第二十五课

    使用具名参数 直接看代码: db.properties jdbc.user=root jdbc.password=logan123 jdbc.driverClass=com.mysql.jdbc.Dr ...

随机推荐

  1. 第二十三篇、IO多路复用 二

    基于IO多路复用实现socket的连接 下面流程:1.先创建列表,让自己的socket对象传入,然后遍历select第一个参数2.客户端连接,那么客户端socket就传入到了列表里面,3.遍历,接收客 ...

  2. 一看就懂的数据库范式介绍(1NF,2NF,3NF,BC NF,4NF,5NF)

    原文:http://josh-persistence.iteye.com/blog/2200644 一.基本介绍 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称 ...

  3. 大话设计模式--命令模式 Command -- C++实现实例

    1. 命令模式: 将请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式有点: a. 较容易的设计一个命令队列 b. 在需要的的情况 ...

  4. Android 动态权限申请

    package com.dragon.android.permissionrequest; import android.Manifest; import android.content.Dialog ...

  5. jQuery绑定事件的四种方式区别

    jQuery中提供了四种事件监听方式,分别是bind.live.delegate.on,对应的解除监听的函数分别是unbind.die.undelegate.off.在开始看他们之前 一:bind(t ...

  6. dos命令行中不同磁盘的调转

    windows下,dos中不同磁盘的跳转: 直接 盘符+回车: 如跳转到d盘: D:回车即可 : Microsoft Windows [版本 10.0.10586] (c) 2015 Microsof ...

  7. hdu 2018 母牛的故事(简单dp)

    母牛的故事 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. php导出内容到txt并自动弹出下载文件

    php将内容保存到txt文件中,并自动弹出下载文件窗口的方法: $id=array('我爱学习网http://www.5ixuexiwang.com','汇享在线工具箱http://tool.huix ...

  9. codeforces 707C C. Pythagorean Triples(数学)

    题目链接: C. Pythagorean Triples time limit per test 1 second memory limit per test 256 megabytes input ...

  10. PostgreSQL正则及模糊查询优化

    1.带前缀的模糊查询  ~'^abc' 可以使用btree索引优化 create index idx_info on table_name(info) 2.带后缀的模糊查询  ~'abc$' 可以使用 ...