Spring学习(四)
Spring Ioc容器
1、具有依赖注入功能的容器。负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。在Spring中BeanFactory是Ioc容器的实际代表者。BeanFactory接口提供了IoC容器的基本功能。Spring Ioc容器通过读取配置文件中的配置元数据,通过元数据对应用中各个对象进行实例化及装配。

Spring Ioc容器管理的对象:Bean
1、定义
- Bean就是由Spring容器初始化、装配及管理的对象,此外bean与应用程序中的其他对象没有什么区别.
- Bean在容器内部由BeanDefinition对象表示。
2、BeanDefinition
- 全限定类名(FQN):用于定义Bean的实现类;(必须的)
- Bean行为定义:包括作用域(单例、原型创建)、是否惰性初始化及生命周期等;
- Bean创建方式定义:说明是通过构造器还是工厂方法创建Bean;
- Bean之间关系定义:即对其他bean的引用,也就是依赖关系定义,也就是依赖注入。
3、Bean的作用域
- “singleton”(单例,通过单例缓存池实现)
- “prototype”(原型,每次创建全新的bean)
- 另外提供“request”、“session”、“global session”三种web作用域
Spring IoC容器创建Bean 的方式
1、根据Bean定义里的配置元数据使用反射机制来创建Bean。
- 使用构造
- 静态工程方法
- 实例工厂方法
- 使用 FactoryBean 方式
2、使用构造: 创建对象使用无参构造的方式,使用最多的一种方式,注入数据用setter 方法
Fox类
package ecut.ioc.creation;
public class Fox {
private String id ;
private String name ;
public Fox() {
super();
System.out.println( "Fox 无参构造" );
}
public Fox(String id , String name) {
super();
this.id = id;
this.name = name;
System.out.println( "Fox( String , String ) 构造" );
}
@Override
public String toString() {
return "Fox [id=" + id + ", name=" + name + "]";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
constructor-creation.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-4.3.xsd"> <!-- 调用无参构造 -->
<bean id="fox1" class="ecut.ioc.creation.Fox" >
<property name="id" value="A001" />
<property name="name" value="苏妲己" />
</bean>
<!-- 使用名称调用有参构造 ,建议使用可读性好-->
<bean id="fox2" class="ecut.ioc.creation.Fox" >
<constructor-arg name="id" value="B001" />
<constructor-arg name="name" value="雪山飞狐" />
</bean>
<!-- 使用索引调用有参构造 -->
<bean id="fox3" class="ecut.ioc.creation.Fox" >
<constructor-arg index="0" value="B002" />
<constructor-arg index="1" value="旋涡鸣人" />
</bean>
</beans>
测试类
package ecut.ioc.creation; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanCreationByConstructor { public static void main(String[] args) { String configLocations = "classpath:ecut/**/constructor-creation.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); //需要有无参构造,不然会抛出BeanCreationException,因为没有指定默认的构造函数
Fox fox1 = container.getBean( "fox1" , Fox.class );
System.out.println( fox1 ); Fox fox2 = container.getBean( "fox2" , Fox.class );
System.out.println( fox2 ); Fox fox3 = container.getBean( "fox3" , Fox.class );
System.out.println( fox3 ); container.close(); } }
3、静态工程方法:某个类里面有一个方法专门用创建这个类的对象
Sun类
package ecut.ioc.creation;
public class Sun {
/*//"饿汉"式实现单例
private static final Sun SUN =new Sun();
private Sun(){
super();
System.out.println( "构造方法执行" );
}
//调用getInstance()方法获取sun类型实例,调用类的静态方法是主动使用会导致 类被初始化
public static Sun getInstance(){
System.out.println( "使用静态方法返回 Sun 类型的实例" );
//这个Sun 类型的实例是单例的
return SUN ;
}*/
//懒汉式,线程安全实现单例
private static Sun SUN ;
private Sun(){
super();
System.out.println( "构造方法执行" );
}
//调用getInstance()方法获取sun类型实例,调用类的静态方法是主动使用会导致 类被初始化
public static Sun getInstance(){
System.out.println( "使用静态方法返回 Sun 类型的实例" );
//同步锁是类对应对象
synchronized ( Sun.class ) {
SUN = new Sun();
}
//这个Sun 类型的实例是单例的
return SUN ;
}
}
static-factory-method.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-4.3.xsd"> <!-- factory-method指定的是静态方法,通过调用静态方法之前 -->
<bean id="sun"
class="ecut.ioc.creation.Sun"
factory-method="getInstance" /> </beans>
测试类
package ecut.ioc.creation; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanCreationByStaticFactory { public static void main(String[] args) { String configLocations = "classpath:ecut/**/static-factory-method.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); System.out.println( "~~~~~~~~~~~~~~~~~" );
//构造方法只执行一次,默认情况下,容器创建就已经创建了这个bean
Sun s = container.getBean( "sun" , Sun.class );
System.out.println( s ); Sun x = container.getBean( "sun" , Sun.class );
System.out.println( x ); container.close(); } }
4、实例工厂方法:要有一个具体的工厂实例,有这个工厂实例去造bean
Car类
package ecut.ioc.creation;
public class Car {
private String brand ; // 品牌
public Car(){
super();
System.out.println( "Car无惨构造执行" );
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
CarFactory类
package ecut.ioc.creation;
public class CarFactory {
private String brandName ;
public CarFactory() {
super();
}
public CarFactory(String brandName) {
super();
this.brandName = brandName;
System.out.println( "CarFactory( String ) 构造执行" );
}
public Car create(){
System.out.println( "准备创建 Car 的实例" );
Car c = new Car();
c.setBrand( brandName );
return c ;
}
}
instance-factory-method.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-4.3.xsd"> <!-- 先 创建 Car 工厂 -->
<bean id="carFactory" class="ecut.ioc.creation.CarFactory" >
<constructor-arg name="brandName" value="BYD" />
</bean> <!-- 再 通过 工厂实例 ( carFactory ) 的 非静态方法来创建 Car -->
<bean id="car" factory-bean="carFactory" factory-method="create" /> </beans>
测试类
package ecut.ioc.creation; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanCreationByInstanceFactory { public static void main(String[] args) { String configLocations = "classpath:ecut/**/instance-factory-method.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); System.out.println( "~~~~~~~~~~~~~~~~~" ); Car c = container.getBean( "car" , Car.class );
System.out.println( c.getBrand() ); container.close(); } }
5、使用 FactoryBean 方式:FactoryBean 是一个接口,由FactoryBean类型的对象造另外一个对象
DateFactoryBean
package ecut.ioc.creation; import java.util.Calendar;
import java.util.Date; import org.springframework.beans.factory.FactoryBean;
//期望返回的类型xx,则xxFactoryBean implements FactoryBean<xx>
public class DateFactoryBean implements FactoryBean<Date>{ private int year ;
private int month ;
private int date ;
private int hour ;
private int minute ;
private int second ; private static final Calendar CALENDAR = Calendar.getInstance(); public DateFactoryBean(){
super();
System.out.println( "DateFactoryBean()" );
} @Override
public Date getObject() throws Exception {
System.out.println( "准备获取 Date 类型实例" );
CALENDAR.set( year, month - 1 , date , hour , minute , second );
Date date = CALENDAR.getTime();
return date ;
} @Override
public Class<?> getObjectType() {
return Date.class;
} @Override
public boolean isSingleton() {
return false;
} public int getYear() {
return year;
} public void setYear(int year) {
this.year = year;
} public int getMonth() {
return month;
} public void setMonth(int month) {
this.month = month;
} public int getDate() {
return date;
} public void setDate(int date) {
this.date = date;
} public int getHour() {
return hour;
} public void setHour(int hour) {
this.hour = hour;
} public int getMinute() {
return minute;
} public void setMinute(int minute) {
this.minute = minute;
} public int getSecond() {
return second;
} public void setSecond(int second) {
this.second = second;
} }
约定:期望返回的类型xx,则xxFactoryBean implements FactoryBean<xx>
factory-bean-creation.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-4.3.xsd"> <!-- 以前: 指定 class 是什么类型,就返回什么类型的实例 -->
<bean id="d" class="java.util.Date" /> <!-- 以前: 指定 class 是什么类型,就返回什么类型的实例,且是使用无参构造 创建bean,则必须要有无参构造-->
<bean id="fox1" class="ecut.ioc.creation.Fox" >
<property name="id" value="A001" />
<property name="name" value="苏妲己" />
</bean> <!-- 这里: 指定的 class 是 XxxFactoryBean ,但是返回的却不是 XxxFactoryBean 类型的实例 -->
<!-- 而是返回了 XxxFactoryBean 内部的 getObject 方法所返回的那个实例 -->
<bean id="birthdate" class="ecut.ioc.creation.DateFactoryBean" >
<property name="year" value="1997" />
<property name="month" value="7" />
<property name="date" value="1" />
<property name="hour" value="12" />
<property name="minute" value="30" />
<property name="second" value="18" />
</bean> </beans>
测试类
package ecut.ioc.creation; import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date; import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanCreationByFactoryBean { public static void main(String[] args) { String configLocations = "classpath:ecut/**/factory-bean-creation.xml" ; AbstractApplicationContext container = new ClassPathXmlApplicationContext( configLocations ); Date d = container.getBean( "birthdate" , Date.class );
System.out.println( d ); DateFormat df = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" ); System.out.println( df.format( d ) ); container.close(); } }
转载请于明显处标明出处
https://www.cnblogs.com/AmyZheng/p/9249550.html
Spring学习(四)的更多相关文章
- spring学习(四) ———— 整合web项目(SSH)
清楚了spring的IOC 和 AOP,最后一篇就来整合SSH框架把,记录下来,以后应该会用的到. --WH 一.web项目中如何使用spring? 当tomcat启动时,就应该加载spring的配置 ...
- Spring学习(四)--面向切面的Spring
一.Spring--面向切面 在软件开发中,散布于应用中多处的功能被称为横切关注点(cross- cutting concern).通常来讲,这些横切关注点从概念上是与应用的业 务逻辑相分离的(但是往 ...
- spring学习四:springMVC
ref:http://www.cnblogs.com/ysocean/tag/SpringMVC%E5%85%A5%E9%97%A8%E7%B3%BB%E5%88%97/ Spring MVC的处理流 ...
- spring学习 四 对象的创建
spring中,有三种创建对象的方式 (1)构造创建 (2)实例工厂构造 (3)静态工厂构造 一 构造器创建 在构造器创建对象时,有无参构造和有参构造 两种 (1)在spring中,默认的是无参构造 ...
- Spring学习(四)-----Spring Bean引用同xml和不同xml bean的例子
在Spring,bean可以“访问”对方通过bean配置文件指定相同或不同的引用. 1. Bean在不同的XML文件 如果是在不同XML文件中的bean,可以用一个“ref”标签,“bean”属性引用 ...
- Spring学习四----------Bean的配置之Bean的配置项及作用域
© 版权声明:本文为博主原创文章,转载请注明出处 Bean的作用域(每个作用域都是在同一个Bean容器中) 1.singleton:单例,指一个Bean容器中只存在一份(默认) 2.prototype ...
- spring学习四:Spring中的后置处理器BeanPostProcessor
BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...
- Spring学习四
1先导入 Asject的jar包 2配置文件加入标签 ,并加入 <aop:aspectj-autoproxy proxy-target-class="true">(如果 ...
- 我的Spring学习记录(四)
虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...
随机推荐
- vue音乐播放器
利用vue写一个简单的音乐播放器,包括功能有歌曲搜索.歌曲播放.歌曲封面.歌曲评论.播放动画.mv播放六个功能. <template> <div class="wrap&q ...
- centos 7 添加swap
[root@lab01 /]# cd / [root@lab01 /]# + records in + records out bytes ( MB/s [root@lab01 /]# free -m ...
- ALSA driver--HW Buffer
当app在调用snd_pcm_writei时,alsa core将app传来的数据搬到HW buffer(即DMA buffer)中,alsa driver从HW buffer中读取数据传输到硬件播放 ...
- SQL Server不同服务器不同数据库间的操作
什么是跨服务器操作? 跨服务器操作就是可以在本地连接到远程服务器上的数据库,可以在对方的数据库上进行相关的数据库操作,比如增删改查. 为什么要进行跨服务器操作 随着数据量的增多,业务量的扩张,需要在不 ...
- javascript中offsetWidth、clientWidth、width、scrollWidth、clientX、screenX、offsetX、pageX
原文:https://www.cnblogs.com/ifworld/p/7605954.html 元素宽高 offsetWidth //返回元素的宽度(包括元素宽度.内边距和边框,不包括外边距) o ...
- 怎么拆分一个Excel工作簿中的多个工作表?
打开需要编辑的Excel文档.如图所示,工作簿下方有很多工作表.现在需要将这些工作表单独拆分开成一个个工作簿. 右键任意一个工作表标签,在弹出的下拉列表中选择查看代码.即弹出代码窗口.如下图所示. ...
- 计算机二级-C语言-字符数字转化为整型数字。形参与实参类型相一致。double类型的使用。
//函数fun功能:将a和b所指的两个字符串分别转化成面值相同的整数,并进行相加作为函数值返回,规定只含有9个以下数字字符. //重难点:字符数字转化为整型数字. #include <stdio ...
- JS-原生的ajax
记录一下: //post需要设置请求头 setRequestHeader(name, value)name //头部的名称:这个参数不应该包括空白.冒号或换行 //value 头部的值:这个参数不应该 ...
- php 基础 自动类型转换
1.自动类型转换:表示运算的时候,Boolean,Null,String等类型,会先自动转为Integer或Float类型 null-->0 true-->1 false-->0 S ...
- 学好Linux必备知识
鸟哥的私房菜中提到学好Linux必备的几种技能: 1. 计算器概论不硬件相关知识: 因为既然想要走Linux这门路,信息相关癿基础技能也丌能没有啊! 所以先理觋一下基础癿硬件知识,丌用一定要全懂啦! ...