JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)
一、IOC控制反转概念
控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式。
主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器,基于这种被动形式,我们就是对象被反转了。
二、Spring IoC容器的初始化和依赖注入
Bean的定义何处是花再Spring Ioc容器中是两大步骤,它是先定义,然后初始化和依赖注入。
Bean的定义分为3步:
(1)Resource定位,这步是Spring IoC容器根据开发者的配置,进行资源定位,在Spring的开发中,通过xml和注解都是十分常见的方式,
定位的内容是由开发者所提供的。
(2)BeanDefinition的载入,这个时候只是将Resource定位到的信息,保存到Bean定义(BeanDefinition)中,此时不会创建Bean的实例。
(3)BeanDefinition的注册,这个过程就是将BeanDefinition的信息发布到Spring IoC容器中,注意此时仍没有对应的Bean的实例被创建。
做完上述3个步骤,Bean就在Spring IoC容器中被定义,而没有被初始化,更没有完成依赖注入,也就是说没有注入资源给Bean,那么它还不能完全使用。
对于初始化和依赖注入,SpringBean还有一个配置选项--lazy-init,其含义就是是否初始化Spring Bean。在没有任何配置的情况下,它的默认值未default,
实际值是false,也就是说Spring IoC容器会默认自动初始化Bean,如果将它的值设置为true,那么只有我们使用Spring IoC容器的getBean方法获取它时,它才会
进行Bean的初始化,完成依赖注入。
三、Sprng Bean的生命周期:
Spring IoC容器的本质目的就是为了管理Bean。对于Bean而言,在容器中存在其生命周期,它的初始化和销毁也需要一个过程,在一些需要自定义的过程中,我们可
插入代码取改变它们的一些行为,以满足特定的需求,这就需要使用到Spring Bean的生命周期的知识了。
生命周期主要是为了了解Spring IoC容器初始化和销毁Bean的过程,通过对它的学习就可以知道如何在初始化和销毁的时候加入自定义的方法,以满足特定的需求。
以下是展示Spring IoC容器初始化和销毁Bean的过程
Spring Bean生命周期的步骤:
(1)如果Bean实现了接口BeanNameAware的setBeanName方法,那么它就会调用这个方法。
(2)如果Bean实现了接口BeanFactoryAware的setBeanFactory方法,那么它就会调用这个方法。
(3)如果Bean实现了接口ApplicationContextAware接口的setApplicationContext方法,且Spring IoC容器也必须有一个ApplicationContext接口的实现子类,
那么才会调用这个方法,否则是不调用的。
(4)如果Bean实现了BeanPostProcessBeforeInitalization方法,那么它会调用这个方法。
(5)如果Bean实现了接口BeanFactoryPostProcessor的afterPropertiesSet方法,那么它就会调用这个方法。
(6)如果Bean自定义了初始化方法,它就会调用已定义的初始化方法。
(7)如果Bean实现接口BeanPostProcessor的postProcessAfterInitialization方法,完成了这些调用,这个时候Bean就完成了初始化,那么Bean就生存在Spring IoC
的容器中了,使用者就可以从中获取Bean的服务。
当服务器正常关闭,或者遇到其他关闭SpringIoC容器的事件,它就会调用对应的方法来完成Bean的销毁,其步骤如下:
(1)如果Bean实现了接口DisposableBean的Destory方法,那么就会调用它。
(2)如果定义了自定义销毁方法,那么就会调用它。
四、Spring Bean生命周期测试
创建一个POJO类:UserBean.java
package com.xfwl.spring.beans;
/**
* Pojo实体类
* @author Jason
*
*/
public class UserBean {
private String uname;
private String upwd;
public UserBean(){}
public UserBean(String uname,String upwd){
this.uname=uname;
this.upwd=upwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpwd() {
return upwd;
}
public void setUpwd(String upwd) {
this.upwd = upwd;
}
}
创建一个管理类:Manager.java
package com.xfwl.spring.beans; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
*
* @function
* @author 小风微凉
* @time 2018-7-10 上午11:32:01
*/
public class Manager implements BeanNameAware, BeanFactoryAware,ApplicationContextAware, InitializingBean,DisposableBean{
/**属性和setter、getter方法**/
private UserBean user=null; public UserBean getUser() {
return user;
}
public void setUser(UserBean user) {
this.user = user;
} /**Bean生命周期测试**/
public void init(){
System.out.println("【"+this.getClass().getSimpleName()+"】执行自定义初始化方法!");
}
public void mydestory(){
System.out.println("【"+this.getClass().getSimpleName()+"】执行自定义销毁法!");
}
public void login(){
System.out.println("【登录操作】,登录信息:uname:"+this.user.getUname()+",upwd="+this.user.getUpwd());
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【"+this.getClass().getSimpleName()+"】调用了InitializingBean接口的afterPropertiesSet方法!");
} @Override
public void setApplicationContext(ApplicationContext arg0)throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】调用了ApplicationContextAware接口的setApplicationContext方法!");
} @Override
public void setBeanFactory(BeanFactory arg0) throws BeansException {
System.out.println("【"+this.getClass().getSimpleName()+"】调用了BeanFactoryAware接口的setBeanFactory方法!");
} @Override
public void setBeanName(String arg0) {
System.out.println("【"+this.getClass().getSimpleName()+"】调用了BeanNameAware接口的setBeanName方法!");
}
@Override
public void destroy() throws Exception {
System.out.println("调用接口DisposableBean的destory方法!");
}
}
配置: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-2.0.xsd">
<!-- <bean id="user_Tom" class="com.xfwl.spring.beans.UserBean">
<property name="uname" value="tom"></property>
<property name="upwd" value="123"></property>
</bean>
<bean id="user_Jack" class="com.xfwl.spring.beans.UserBean">
<property name="uname" value="jack"></property>
<property name="upwd" value="123"></property>
</bean> -->
<bean id="user_xfwl" class="com.xfwl.spring.beans.UserBean">
<property name="uname" value="小风微凉"></property>
<property name="upwd" value="123456"></property>
</bean>
<bean id="BeanPostProcessorImpl" class="com.xfwl.spring.beans.BeanPostProcessorImpl"/>
<bean id="manager" class="com.xfwl.spring.beans.Manager"
init-method="init" destroy-method="mydestory" lazy-init="default">
<property name="user" ref="user_xfwl"></property>
</bean>
</beans>
创建一个测试类:TestBean.java
package com.xfwl.spring.beans;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext; /**
* Spring Ioc测试
* @function
* @author 小风微凉
* @time 2018-7-10 上午9:55:15
*/
public class TestBean {
//绝对路径
private static final String xmlAbsPath="E:\\JAVA学习[【进阶学习】\\JAVA回炉深造\\进阶测试工作空间\\多线程\\SpringSources\\src\\applicationContext.xml";
//项目相对路径
private static final String xmlRelPath="applicationContext.xml";
public static void main(String[] args) {
/*//第一种解析方式
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlAbsPath);
UserBean tom =(UserBean) ctx.getBean("user_Tom");
System.out.println(tom.getUname()); //第二种解析方式
ApplicationContext context=new ClassPathXmlApplicationContext(xmlRelPath);
UserBean jack =(UserBean) context.getBean("user_Jack");
System.out.println(jack.getUname());*/ //测试Bean的生命周期
FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(xmlAbsPath);
Manager manager =(Manager) ctx.getBean("manager");
manager.login();
ctx.close();
}
}
运行结果:
log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
【UserBean】对象:user_xfwl开始实例化
【UserBean】对象:user_xfwl完成实例化
【Manager】调用了BeanNameAware接口的setBeanName方法!
【Manager】调用了BeanFactoryAware接口的setBeanFactory方法!
【Manager】调用了ApplicationContextAware接口的setApplicationContext方法!
【Manager】对象:manager开始实例化
【Manager】调用了InitializingBean接口的afterPropertiesSet方法!
【Manager】执行自定义初始化方法!
【Manager】对象:manager完成实例化
【登录操作】,登录信息:uname:小风微凉,upwd=123456
调用接口DisposableBean的destory方法!
【Manager】执行自定义销毁法!
可以看到,在applicationContext.xml中配置一个Bean,然后getBean(),整个Bean的生命周期。
五、上文中Spring的Jar配置說明
1.Spring依赖包配置:(核心功能:IOC容器)
*spring的核心jar包:spring.jar
*spring-context.jar包:获取xml配置bean对象的相关类支持,比如ApplicationContext.java
*spring-beans.jar包:获取xml配置bean对象的相关类支持,比如BeanFactory.java
*spring-expression.jar:提供类的支持,比如:FileSystemXmlApplicationContext.java,用于解析xml配置信息
*记录日志jar包:log4j.jar
*apache的记录日志jar包:commons-logging.jar(日志的抽象) 特别说明:
如果项目的.classpath中有log4j.jar,那么会优先用log4j.jar,
如果没有log4j.jar,则会会调用sun的JDK中的记录日志的工具包,
如果都没有,最后使用:commons-logging.jar 会调用本身的日志记录功能来记录日志 commons-logging.jar是日志功能的抽象,
优先级别如下:
log4j.jar-->jdk本身的日志功能-->commons-logging.jar本身的日志记录功能
JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)的更多相关文章
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件
一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)
一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)
一. 装配Bean概述 关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配
一.依赖注入的三种方式 在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解
一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解
一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)
一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean
一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式
一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景. 2. ...
随机推荐
- composer安装特别慢的解决方案
在项目开发的时候 有许多新的依赖要按照 就需要用到composer 但是由于国内安装下载速度贼慢(国外的网站连接速度太慢,并且随时可能被墙) 安装一个excel扩展(composer require ...
- java中输入3个数,从大到小的输出。。。。
总结:我暂时不能理解,C语言时讲过,java里就不理解了 package com.a; import java.sql.Date; import java.util.Scanner; //输入三个数, ...
- PHP中的逻辑判断函数empty() isset() is_null() ==NULL ===NULL
1.empty() header("Content-type: text/html; charset=utf-8"); if(!empty($data)){ //empty() 未 ...
- Three.js会飞走飞回来的鸟
效果图 demo import './index.css'; // stats var stats; (function(){ stats = new Stats(); document.body.a ...
- Java面向对象-构造方法,this关键字
Java面向对象-构造方法,this关键字 构造方法 概念:构造方法是一个特殊的方法,这个特殊方法用于创建实例时执行初始化操作: 上代码: package com.java1234.chap03.se ...
- JQuery UI Datepicker中文显示的方法
出自:http://www.aimks.com/method-to-display-the-jquery-ui-datepicker-chinese.html Query UI Datepicker这 ...
- angularJS笔记之 服务
angular的服务有五种 第一种 constant 一般作为一种常量的服务 不可更改 第二种 value 用来注册服务对象或函数 可更改 第三种 factory 创建和配置服务的最快捷方式.可更改 ...
- ASP.NET MVC 基于表达式的动态查询
项目源码地址:https://gitee.com/zhengwei804/DynamicCustomSearch
- JAVA基础知识总结15(集合容器)
集合框架:用于存储数据的容器. 1:对象封装数据,对象多了也需要存储.集合用于存储对象. 2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合.因为集合是可变长度的. 集合和数组的区别: 1: ...
- Dubbo+zookeeper应用的入门案例
前提:Linux安装zookeeper Dubbo管理中心部署 简单案例的项目结构: 1,demo_parent的pom.xml,用来统一管理依赖 <?xml version="1. ...