Java程序员从笨鸟到菜鸟之(七十)细谈Spring(三)IOC和spring基本配置详解
对于IoC 的一些知识点,相信大家都知道他在spring框架中所占有的地位,应该可以算的上是核心之一吧,所以IOC是否理解清楚,决定了大家对Spring整个框架的理解
Ioc的理解
spring 的两个核心概念:一个是控制反转IoC,也可以叫做依赖注入DI。还有一个是面向切面编程AOP。
控制反转:当某个Java 对象需要(依赖)另一个java 对象时,不
是自身直接创建依赖对象,而是由实现IoC 的容器(如spring 框架的IoC容器)来创建,并将它注入需要这个依赖对象的java 对象中。
spring 的容器
spring 管理的基本单元是Bean,在spring 的应用中,所有的组件都是一个个的Bean,它可以是任何的java 对象。spring 负责创建这些Bean的实例。并管理生命周期。而spring 框架是通过其内置的容器来完成Bean 的管理的,Bean 在spring 的容器中生存着,使用时只需要通过它提供的一些方法从其中获取即可。
spring 的容器有两个接口:BeanFactory 和ApplicationContext 这两个接口的实例被陈为spring 的上下文。
- <span style="font-size:18px;">ApplicationContext ac = newClassFathXmlApplicationContext("app*.xml");
- AccountService accountService =(AccountService)ac.getBean("accountServiceImpl");</span>
注:由于ApplicationContext是基于BeanFactory之上的,所以,一般ApplicationContext功能比较强大,建议使用
ApplicationContext经常用到的三个实现:
1.ClassPathXmlApplicationContext:从类路径中的XML文件载入上下文定义信息。把上下文定义文件当成类路径资源。
2.FileSystemXmlApplicationContext:从文件系统中的XML文件载入上下文定义信息。
3.XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息。
一:spring 的依赖注入
1)、构造器注入
- <span style="font-size:18px;"><bean id="accoutDaoImpl" class="cn.csdn.dao.AccoutDaoImpl"
- scope=”singleton”/>
- <bean id="accoutServicImpl"
- class="cn.csdn.service.AccoutServicImpl" scope=”">
- <!-- 构造方法注入方式-->
- <constructor-arg ref="accoutDaoImpl"/>
- </bean></span>
注:这种注入方式很少用,如果是注入对象一般为上例注入,但有时要注入基本数据类型,一般用下面方法注入
- <span style="font-size:18px;"><constructor-arg>
- <value>hello world!</value>
- </constructor-arg></span>
如果构造方法不只一个参数时,应指明所注入参数的索引或者数据类型,例如:
- <span style="font-size:18px;color:#333333;"><constructor-arg index="0" type="java.lang.String">
- <value>sunDriver</value>
- </constructor-arg>
- <constructor-arg index="1" type="java.lang.String">
- <value>jdbc:odbc:School</value>
- </constructor-arg></span>
2)、设值(set 方法)注入
- <span style="font-size:18px;"><bean id="accountDaoImpl"
- class="cn.csdn.dao.AccoutDaoImpl"/>
- <bean id="accoutServicImpl"
- class="cn.csdn.service.AccoutServicImpl">
- <!-- 设值(set 方法)注入-->
- <property name="accountDaoImpl" ref="accoutDaoImpl"/>
- </bean></span>
注:<property name="accountDaoImpl" ref="accoutDaoImpl"/>
相当于调用set AccountDaoImpl方法,把值设为accoutDaoImpl
3)接口注入(很少用)
二: xml 装配Bean属性含义
1.id:指定该Bean 的唯一标识。
2.class:指定该Bean 的全限定名。
3.name:为该Bean 指定一到多个别名。多个别名可以用“,”和“;”分割。
4.autowire:指定该Bean 的属性的装配方式。
所谓自动装配是指在<BEAN>标签中不用指定其依赖的BEAN,而是通过配置的自动装配来自动注入依赖的BEAN,这种做法让我们的配置更加简单
1)no:不使用自动装配。必须通过ref 元素指定依赖,这是默认设置。由于显式指定协作者可以使配置更灵活、更清晰,因此对于较大的部署配置,推荐采用该设置。而且在某种程度上,它也是系统架构的一种文档形式。
- <span style="font-size:18px;"><bean id="bean1" class="cn.csdn.service.Bean1"
- scope="singleton">
- <property name="studentDaoImpl"
- ref="studentDaoImpl">
- </property>
- </bean></span>
备注:有property 属性指定ref
2)byName:根据属性名自动装配。此选项将检查容器并根据
名字查找与属性完全一致的bean,并将其与属性自动装配。例如,在
bean 定义中将autowire 设置为by name,而该bean 包含master 属性(同时提供setMaster(..)方法),Spring 就会查找名为master 的bean 定义,并用它来装配给master 属性。
<bean id="bean1" class="cn.csdn.service.Bean1"
scope="singleton" autowire="byName"/>
备注:没有property 属性
3)byType:如果容器中存在一个与指定属性类型相同的
bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么
将会抛出异常,并指出不能使用byType 方式进行自动装配。若没有找到相匹配的bean,则什么事都不发生,属性也不会被设置。如果你不希望这样,那么可以通过设置dependency-check="objects"让Spring 抛出异常。
备注:spring3.0 以上不抛异常。
<bean id="bean1" class="cn.csdn.service.Bean1"
scope="singleton" autowire="byType"/>
备注:没有property 属性
4)Constructor:与byType 的方式类似,不同之处在于它应用
于构造器参数。如果在容器中没有找到与构造器参数类型一致的bean,那么将会抛出异常。
<bean id="bean1" class="cn.csdn.service.Bean1"
scope="singleton"autowire="constructor"/>
备注:没有property 属性
5)autodetect:通过bean 类的自省机制(introspection)来决定是使用constructor 还是byType 方式进行自动装配。如果发现默认的
构造器,那么将使用byType 方式。
<bean id="bean1" class="cn.csdn.service.Bean1"
scope="singleton" autowire="autodetect"/>
5.scope:指定该Bean 的生存范围
scope用来声明IOC容器中的对象应该处的限定场景或者说该对象的存活空间,即在IOC容器在对象进入相应的scope之前,生成并装配这些对象,在该对象不再处于这些scope的限定之后,容器通常会销毁这些对象。
1) singleton类型的bean定义,在一个容器中只存在一个实例,所有对该类型bean的依赖都引用这一单一实例
2) scope为prototype的bean,容器在接受到该类型的对象的请求的时候,会每次都重新生成一 个新的对象给请求方,虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有 当前对象的引用,请求方需要自己负责当前对象后继生命周期的管理工作,包括该对象的销毁
3) request ,session和global session
这三个类型是spring2.0之后新增的,他们只适用于web程序,通常是和XmlWebApplicationContext共同使用
request:
<bean id ="requestPrecessor" class="...RequestPrecessor" scope="request" />
Spring容器,即XmlWebApplicationContext 会为每个HTTP请求创建一个全新的RequestPrecessor对象,当请求结束后,,该对象的生命周期即告结束
session
<bean id ="userPreferences" class="...UserPreferences" scope="session" />
Spring容器会为每个独立的session创建属于自己的全新的UserPreferences实例,他比request scope的bean会存活更长的时间,其他的方面真是没什么区别。
global session:
<bean id ="userPreferences" class="...UserPreferences" scope="globalsession" />
global session只有应用在基于porlet的web应用程序中才有意义,他映射到porlet的global范围的session,如果普通的servlet的web 应用中使用了这个scope,容器会把它作为普通的session的scope对待。
6.init-method:指定该Bean 的初始化方法。destroy-method:指定该Bean 的销毁方法。这个就像servlet中init和destroy方法一样,只不过这里在配置文件配置的
7.abstract:指定该Bean 是否为抽象的。如果是抽象的,则
spring 不为它创建实例。
8.parent
如果两个Bean 的属性装配信息很相似,那么可以利用继
承来减少重复的配置工作。
<!-- 装配Bean 的继承
父类作为模板,不需要实例化,设置abstract=”true”-->
` <bean id=”parent” class=”cn.csdn.service.Parent”
abstract=”true”>
<property name=”name” value=”z_xiaofei168”/>
<property name=”pass” value=”z_xiaofei168”/>
</bean>
<!-- 装配Bean 的继承
子类中用parent 属性指定父类标识或别名
子类可以覆盖父类的属性装配,也可以新增自己的属性装配
-->
` <bean id=”child” class=”cn.csdn.service.Chlid”
parent=”parent”>
<property name=”pass” value=”123123”/>
<property name=”age” value=”22”/>
</bean>
三:装配Bean 的各种类型属性值
1..简单类型属性值的装配
- <span style="font-size:18px;"><bean id="bean1" class="cn.csdn.domain.Bean1">
- <property name="name" value="z_xiaofei168"/>
- <property name="age">
- <value>22</value>
- </property>
- </bean></span>
2.引用其他Bean 的装配
- <span style="font-size:18px;"><bean id="bean1" class="cn.csdn.domain.Bean1">
- ...
- </bean>
- <bean id="bean2" class="cn.csdn.domain.Bean2">
- <!-- 引用自其他Bean 的装配-->
- <property name="bean1" ref="bean1"/>
- </bean></span>
另外一种不常使用的配置方式是在property 元素中嵌入
一个bean 元素来指定所引用的Bean.
- <span style="font-size:18px;"><bean id="bean1" class="cn.csdn.domain.Bean1">
- ...
- </bean>
- <bean id="bean2" class="cn.csdn.domain.Bean2">
- <!-- 引用自其他Bean 的装配-->
- <property name="bean1">
- <bean id="bean1"
- class="cn.csdn.domain.Bean1"/>
- </property>
- </bean></span>
3.集合的装配
其实集合的装配并不是复杂,反而感觉到很简单,用一个例子来说明问题吧:
- <span style="font-size:18px;">package com.bebig.dao.impl;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import java.util.Set;
- import com.bebig.dao.UserDAO;
- import com.bebig.model.User;
- public class UserDAOImpl implements UserDAO {
- private Set<String> sets;
- private List<String> lists;
- private Map<String, String> maps;
- private Properties props;
- public Set<String> getSets() {
- return sets;
- }
- public void setSets(Set<String> sets) {
- this.sets = sets; }
- public List<String> getLists() {
- return lists; }
- public void setLists(List<String> lists) {
- this.lists = lists; }
- public Map<String, String> getMaps() {
- return maps;
- }
- public void setMaps(Map<String, String> maps) {
- this.maps = maps;
- }
- public Properties getProps() {
- return props;
- }
- public void setProps(Properties props) {
- this.props = props;
- }
- public void save(User u) {
- System.out.println("a user saved!");
- }
- @Override
- public String toString() {
- return "sets.size:" + sets.size() + " lists.size:" + lists.size()
- + " maps.size:" + maps.size() + " props.size:" + props.size();
- }
- }
- </span>
配置如下:
- <span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
- >
- <!-- a service object; we will be profiling its methods -->
- <bean name="u" class="com.bebig.dao.impl.UserDAOImpl">
- <!-- set -->
- <property name="sets">
- <set>
- <value>1</value>
- <value>2</value>
- </set>
- </property>
- <!-- list -->
- <property name="lists">
- <list>
- <value>a</value>
- <value>b</value>
- </list>
- </property>
- <!-- map -->
- <property name="maps">
- <map>
- <entry key="1" value="aa"></entry>
- <entry key="2" value="bb"></entry>
- </map>
- </property>
- <!-- properties -->
- <property name="props">
- <props>
- <prop key="a">haha</prop>
- <prop key="b">hi</prop>
- </props>
- </property>
- </bean>
- <bean id="userService" class="com.bebig.service.UserService"
- scope="prototype">
- <constructor-arg>
- <ref bean="u" />
- </constructor-arg>
- </bean>
- <!-- this switches on the load-time weaving -->
- <!-- <context:load-time-weaver /> -->
- </beans></span>
四:Spring bean生命周期
在传统的Java应用中,Bean的生命周期非常简单。 Java的关键词new用来实例化Bean(或许他是非序列化的)。这样就够用了。 相反,Bean的生命周期在Spring容器中更加细致。 理解Spring Bean的生命周期非常重要,因为你或许要利用Spring提供的机会来订制Bean的创建过程。
bean生命周期
1.容器寻找Bean的定义信息并且将其实例化。
2.受用依赖注入,Spring按照Bean定义信息配置Bean的所有属性。
3.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。
4.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。
5.如果BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialzation()方法将被调用。
6.如果Bean指定了init-method方法,它将被调用。
7.最后,如果有BeanPsotProcessor和Bean关联,那么它们的postProcessAfterInitialization()方法将被调用。
到这个时候,Bean已经可以被应用系统使用了,并且将被保留在Bean Factory中知道它不再需要。
有两种方法可以把它从Bean Factory中删除掉。
1.如果Bean实现了DisposableBean接口,destory()方法被调用。
2.如果指定了订制的销毁方法,就调用这个方法。
Bean在Spring应用上下文的生命周期与在Bean工厂中的生命周期只有一点不同, 唯一不同的是,如果Bean实现了ApplicationContextAwre接口,setApplicationContext()方法被调用。
只有singleton行为的bean接受容器管理生命周期。
non-singleton行为的bean,Spring容器仅仅是new的替代,容器只负责创建。
对于singleton bean,Spring容器知道bean何时实例化结束,何时销毁, Spring可以管理实例化结束之后,和销毁之前的行为,管理bean的生命周期行为主要未如下两个时机:
Bean全部依赖注入之后
Bean即将销毁之前
1)依赖关系注入后的行为实现:
有两种方法:A.编写init方法 B.实现InitializingBean接口
afterPropertiesSet和init同时出现,前者先于后者执行,使用init方法,需要对配置文件加入init-method属性
2)bean销毁之前的行为
有两种方法:A.编写close方法 B.实现DisposableBean接口
destroy和close同时出现,前者先于后者执行,使用close方法,需要对配置文件加入destroy-method属性
总体上分只为四个阶段
1. BeanFactoyPostProcessor实例化
2. Bean实例化,然后通过某些BeanFactoyPostProcessor来进行依赖注入
3. BeanPostProcessor的调用.Spring内置的BeanPostProcessor负责调用Bean实现的接口: BeanNameAware, BeanFactoryAware, ApplicationContextAware等等,等这些内置的BeanPostProcessor调用完后才会调用自己配置的BeanPostProcessor
4.Bean销毁阶段
注:xml依赖注入中的bean.xml例子:
- <span style="font-size:18px;"><?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.5.xsd">
- <bean id="u" class="com.bjsxt.dao.impl.UserDAOImpl">
- </bean>
- <bean id="userService" class="com.bjsxt.service.UserService">
- <!--
- <property name="userDAO" ref="u" />
- -->
- <constructor-arg>
- <ref bean="u"/>
- </constructor-arg>
- </bean>
- </beans></span>
Java程序员从笨鸟到菜鸟之(七十)细谈Spring(三)IOC和spring基本配置详解相关推荐
- Java程序员从笨鸟到菜鸟之(十)枚举,泛型详解
一:首先从枚举开始说起 枚举类型是JDK5.0的新特征.Sun引进了一个全新的关键字enum来定义一个枚举类.下面就是一个典型枚举类型的定义: public enum Color{ RED,BLUE, ...
- Java程序员从笨鸟到菜鸟全部博客目录
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.NET/csh624366188 欢迎关注微信账号:java那些事:csh624366188.每天一篇java相关的文章 大 ...
- Java程序员从笨鸟到菜鸟之(序言)+全部链接
http://blog.csdn.net/csh624366188 大学上了一年半,接触java也一年半了,虽然中间也有其他东西的学习,但是还是以java为主路线,想想这一年半,除去前半年几乎全玩了, ...
- Java程序员由笨鸟到菜鸟 电子版书正式发布 欢迎大家下载
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 欢迎关注 ...
- Java程序员从笨鸟到菜鸟之——总结和声明
前段时间经过大约二十天的时间把javaSE的内容总结了一下,最近由于个人原因和一些乱七八糟的事情,一直没在更新,首先感谢那些一如既往支持我的朋友.最近不知道为什么,一直很懒,做东西也一直是效率很低,生 ...
- Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)...
本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天, ...
- Java程序员从笨鸟到菜鸟之(一百零九)一步一步学习webservice(三)开发第一个基于XFire的webservice
在日常开发中,常用的webservice引擎主要有Axis,axis2,Xfire以及cxf(Xfire的升级版).现在只有axis2和cxf官方有更新.今天我们先以一个比较老的引擎为例.来讲诉一下w ...
- Java程序员从笨鸟到菜鸟之(一百零八)一步一步学习webservice(二)webservice基本原理
本来这第二篇打算讲解"开发第一个基于XFire的webservice"的内容来着.但是想想.开发实例只是局限于了会用的层面上.如果想真正的理解webservice还是需要挖掘其原理 ...
- Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)
写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天,下午我们宿舍聚会,所以时间有点耽误,希望大家见谅 上接: Java程序员从笨鸟到菜鸟之(四)java开发常用类( ...
- Java程序员从笨鸟到菜鸟之(一百零六)java操作office和pdf文件(四)页面列表导出cvs,excel、pdf报表.
在平常的开发中我们常常遇到不仅仅只是导出excel报表的情况.有时候也需要导出pdf或者CSV报表.其实原理都差不多.刚开始本来不打算也这篇博客介绍这个的.感觉这篇博客和前面的博客有点雷同.原理基本都 ...
最新文章
- Flask之Cookie与Session
- torch 判断gpu可用
- python数据分析、整理、汇总展示_python-数据分析与展示(Numpy、matplotlib、pandas)---2...
- C和指针之字符串编程练习10(判断字符串是否是回文数)
- 马拉松教会我_社区教会了我关于开放组织的知识
- Rdlc报表出现空白页解决方法
- JS递归算法经典案例与分析
- Win11桌面便签小工具下载 支持与手机同步的桌面便签工具下载
- 谈一谈软件系统的可用性
- QT FOR 安卓动态旋转屏幕
- Ubuntu22.04 用 `hwclock` 或 `timedatectl` 来设置RTC硬件时钟为本地时区
- 【面试】Tomcat面试题
- win7系统如何映射服务器,映射网络驱动器在Win7系统中的操作方法
- CSDN博客专用动态图小程序的推荐---ScreentoGIF教程
- 微信UI在线聊天源码 聊天系统PHP采用 PHP 编写的聊天软件,简直就是一个完整的迷你版微信
- CVS库,目录入库说明
- 表面纹理:粗糙度Roughness,波纹度waviness和间距spacing
- 日记侠:农妇都开始写软文了,你还等什么?
- 远程控制公司电脑真的很简单
- 火柴人、全jquery、使用jquery制作简单英雄难过棍子关
热门文章
- android manifest简介
- 重磅更新!YoloV4最新论文与源码!权重!结构!翻译!
- 新年到,献给从一线工程师到CTO的实用指南:《2019区块链开发者报告》
- :未来5-10年,NLP将走向成熟
- mysql zf,mysql workbench建表时PK,NN,UQ,BIN,UN,ZF,AI的含义
- 解决 org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does no
- HashMap 的设置值,取值,遍历等
- 一个方法搞定安卓路由跳转
- 山西财经大学计算机考试题及答案,2018年山西财经大学计算机应用技术408计算机学科专业基础综合之计算机操作系统考研基础五套测试题...
- c语言中输入10,10 is greater than 0,2013练习题__Student