这次课我们详细理解一下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. 爬虫 spider

    python 2.x # -*- coding: utf-8 -*-import reimport urllib url = 'http://tieba.baidu.com/p/4872795764' ...

  2. 算法(Algorithms)第4版 练习 2.3.25

      代码实现: public static void sort(Comparable[] a) { StdRandom.shuffle(a);//eliminate dependence on inp ...

  3. linux修改文件所属用户、用户组

    修改hive.log文件为hadoop用户,hadoop组 sudo chown 用户名:用户组 文件 sudo chown hadoop:hadoop hive.log 修改某个文件夹及其自文件 s ...

  4. HDU 4123 Bob's Race:树的直径 + 单调队列 + st表

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 题意: 给你一棵树,n个节点,每条边有长度. 然后有m个询问,每个询问给定一个q值. 设dis[ ...

  5. Selenium-几种元素定位方式

    #识别元素并操作#一般有如下几种方法,其中id最为常用.这里需要注意识别元素一定要用唯一id 1.find_element_by_id("value") #! /usr/bin/e ...

  6. 一次websocket的抓包体验

    一个简单的demo 我们知道websocket一种服务端推送技术,首先Websocket是基于HTTP协议的,或者说借用了HTTP的协议来完成一部分握手.后续数据传递是基于TCP的. 客户端代码 &l ...

  7. codeforces 707B B. Bakery(水题)

    题目链接: B. Bakery 题意: 是否存在一条连接特殊和不特殊的边,存在最小值是多少; 思路: 扫一遍所有边: AC代码: #include <iostream> #include ...

  8. Struts2 - 与 Servlet 耦合的访问方式访问web资源

    •       直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起,  测试时需要有 Servlet 容器, 不便于对 Action 的单元测试. •       ...

  9. Debian for ARM

    /************************************************************************* * Debian for ARM * 说明: * ...

  10. Web Service 之JAX-WS 与CXF实现

    Web Service的实现方式有很多种,本篇介绍的是基于JAX-WS(纯Java)实现的,然后借由CXF工具生成Javabean. 第一步:创建一个Java工程,编写CalService接口,此接口 ...