一、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生命周期)的更多相关文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件

    一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...

  2. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)

    一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...

  3. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)

    一. 装配Bean概述  关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配

    一.依赖注入的三种方式      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...

  5. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解

    一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解

    一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...

  7. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)

    一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean

    一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式

    一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景.   2. ...

随机推荐

  1. 有关Botton的用法(一)

    <Button android:layout_width="wrap_content" android:layout_height="wrap_content&qu ...

  2. Centos7手工安装Kubernetes集群

    安装Kubernetes集群有多种方式,前面介绍了Kubeadm的方式,本文将介绍手工安装的方法. 安装环境有3台Azure上的VM: Hkube01:10.0.1.4 Hkube02:10.0.1. ...

  3. spring-aop + memcached 的简单实现

    一般情况下,java程序取一条数据是直接从数据库中去取,当数据库达到一定的连接数时,就会处于排队等待状态,某些在一定时间内不会发生变化的数据,完全没必要每次都从数据库中去取,使用spring-aop ...

  4. Navicat设定mysql定时任务步骤示例

    怎样在Navicat中设置,是数据库按照记录中的日期更新状态字段 其实这个很常用,比如你网站里的某条记录的日期——比如说数据库中某条活动记录的审核日期字段已经过期,亦即当前时间已经超过审核日期,那么定 ...

  5. Java-Maven-Runoob:Maven 构建 Java 项目

    ylbtech-Java-Maven-Runoob:Maven 构建 Java 项目 1.返回顶部 1. Maven 构建 Java 项目 Maven 使用原型 archetype 插件创建项目.要创 ...

  6. 1032 Sharing

    题意:寻找两个链表的首个公共结点,输出其地址. 思路: 方法1.  如果LinkList1比LinkList2长,则让LinkList1先偏移(len1-len2)个结点,然后,让两个链表的的工作指针 ...

  7. Linux的启动级别

    一.启动级别 1.查看linux 系统默认启动级别cat /etc/inittab id:3:initdefault: ##可以看出默认为三 2.查看某一服务在各个启动级别上是否启动[root@loc ...

  8. 关系数据库元组关系演算语言ALPHA

    关系演算 :以数理逻辑中的谓词演算为基础 按谓词变元不同分类 1.元组关系演算:以元组变量作为谓词变元的基本对象元组关系演算语言ALPHA2.域关系演算:以域变量作为谓词变元的基本对象域关系演算语言Q ...

  9. 关于XSS漏洞的简介以及分类

    不得不说注入的时代已经过去了,最近xss貌似比较热门.我就去恶补了一下,我表示我只是菜鸟,对xss不了解.所以从最基本的学起. 什么xss漏洞? 一.XSS攻击简介 作为一种HTML注入攻击,XSS攻 ...

  10. dubbo学习 一 dubbo概述

    1,背景     1,网站刚开时候的时候可能所有的功能业务都在一个应用里面 2,当业务不断复杂,流量不断增多的时候,就需要将原先的一个应用划分成多个独立的应用. 3,当分出来的业务越来越多的时候,应用 ...