这次课我们详细理解一下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. PHP 邮件发送类

    mail.php <?php /** * 邮件发送类 * 支持发送纯文本邮件和HTML格式的邮件,可以多收件人,多抄送,多秘密抄送,带附件的邮件 * 需要的php扩展,sockets和Filei ...

  2. 20145229吴姗珊 《Java程序设计》第6周学习总结

    20145229吴姗珊 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 输入\输出 1.java将输入\输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象 2.输入串 ...

  3. GetTickCount的几个案例

    一,获得运行时间: var T1,T2 : double; begin T1 := GetTickCount; //需要做的事情 T2 := GetTickCount; ShowMessage( fl ...

  4. JavaScript在执行代码之前会校验代码,声明变量提前至当前作用域最前面。

    var name = 123; function getName(){ console.log(name); } getName(); 输出123 -------------------------- ...

  5. 启动Hive时报错

    报错信息如下 Logging initialized -bin/lib/hive-common-.jar!/hive-log4j.properties Exception in thread &quo ...

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

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

  7. AngularJS方法 —— angular.copy

    描述: 复制一个对象或者一个数组(好吧,万物皆对象,数组也是一个对象). 如果省略了destination,一个新的对象或数组将会被创建出来: 如果提供了destination,则source对象中的 ...

  8. ACM学习历程—HDU 5012 Dice(ACM西安网赛)(bfs)

    Problem Description There are 2 special dices on the table. On each face of the dice, a distinct num ...

  9. 闪回之 回收站、Flashback Drop (table、index、trigger等)

    一: Flashback Drop 操作流程 模式一:drop table 后未新建同名表 SQL> create table flashdrop as select * from user_o ...

  10. mysql root密码忘记重置

    1.修改/etc/my.cnf文件 找到mysqld选项,增加子项skip-grant-tables 2.重新启动mysql服务 service mysqld restart 3.进入mysql 在s ...