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学习(四)的更多相关文章

  1. spring学习(四) ———— 整合web项目(SSH)

    清楚了spring的IOC 和 AOP,最后一篇就来整合SSH框架把,记录下来,以后应该会用的到. --WH 一.web项目中如何使用spring? 当tomcat启动时,就应该加载spring的配置 ...

  2. Spring学习(四)--面向切面的Spring

    一.Spring--面向切面 在软件开发中,散布于应用中多处的功能被称为横切关注点(cross- cutting concern).通常来讲,这些横切关注点从概念上是与应用的业 务逻辑相分离的(但是往 ...

  3. spring学习四:springMVC

    ref:http://www.cnblogs.com/ysocean/tag/SpringMVC%E5%85%A5%E9%97%A8%E7%B3%BB%E5%88%97/ Spring MVC的处理流 ...

  4. spring学习 四 对象的创建

    spring中,有三种创建对象的方式 (1)构造创建 (2)实例工厂构造 (3)静态工厂构造 一  构造器创建 在构造器创建对象时,有无参构造和有参构造 两种 (1)在spring中,默认的是无参构造 ...

  5. Spring学习(四)-----Spring Bean引用同xml和不同xml bean的例子

    在Spring,bean可以“访问”对方通过bean配置文件指定相同或不同的引用. 1. Bean在不同的XML文件 如果是在不同XML文件中的bean,可以用一个“ref”标签,“bean”属性引用 ...

  6. Spring学习四----------Bean的配置之Bean的配置项及作用域

    © 版权声明:本文为博主原创文章,转载请注明出处 Bean的作用域(每个作用域都是在同一个Bean容器中) 1.singleton:单例,指一个Bean容器中只存在一份(默认) 2.prototype ...

  7. spring学习四:Spring中的后置处理器BeanPostProcessor

    BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcesso ...

  8. Spring学习四

    1先导入 Asject的jar包 2配置文件加入标签 ,并加入 <aop:aspectj-autoproxy proxy-target-class="true">(如果 ...

  9. 我的Spring学习记录(四)

    虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...

随机推荐

  1. 什么是this指针?this的几种指向

    在JavaScript中,this指针是在创建时,由系统默认生成的两个隐式参数之一(另一个是arguments). this指针指向与该函数调用进行隐式关联的一个对象,该对象被称为“函数上下文”. t ...

  2. Codeforces Round #604 (Div. 2)D(构造)

    构造,枚举起点,如果一个序列成立,那么将它reverse依然成立,所以两个方向(从小到大或从大到小)没有区别,选定一个方向进行探测,直到探测不到以后回头,只要所给数据能成立,那么能探测进去就能探测出来 ...

  3. ACM的探索之Keen On Evrything But Triangle(我觉得可以很接近啦!!)

    #include<bits/stdc++.h> using namespace std; int main() { int n,q,l,r; while(cin>>n>& ...

  4. 【做题笔记】P1531 I Hate It

    线段树裸题. 需要注意的地方: 对于一次单点修改操作,需要先判断是否需要修改.注意题目中是"如果当前A学生的成绩低于B,则把ID为A的学生的成绩更改为B,否则不改动.".所以判断条 ...

  5. DFS(深度优先搜索)

    基本概念 深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法. 沿着树的深度遍历树的节点,尽可能深的搜索树的分支.当节点v的所在边都己被探寻过或者在搜 ...

  6. 清晰架构(Clean Architecture)的Go微服务: 程序设计

    我使用Go和gRPC创建了一个微服务,并将程序设计和编程的最佳实践应用于该项目. 我写了一系列关于在项目工作中做出的设计决策和取舍的文章,此篇是关于程序设计. 程序的设计遵循清晰架构(Clean Ar ...

  7. 分享Linux系统快速入门法

    相信看到这篇文章的你一定是想要学习Linux,或者已经在学习Linux的人了,那我们就可以一起探讨一下,学习Linux如何快速入门呢? 首先,希望大家弄清楚自己为什么要学习Linux,有的人是因为兴趣 ...

  8. 关于React Native init 项目时候速度太慢的解决方法

    因为init项目的时候需要下载资源,但又因为react native的网站被墙所以下载很慢,解决方法就是换成淘宝的NPM镜像 我是直接使用了命令去替换了NPM $ npm install -g cnp ...

  9. ASP.NET Core搭建多层网站架构【9.1-使用Autofac代替原生的依赖注入】

    2020/01/30, ASP.NET Core 3.1, VS2019, Autofac.Extensions.DependencyInjection 5.0.1 摘要:基于ASP.NET Core ...

  10. 4_5 追踪电子表格中的单元格(UVa512)(选做)

    在电子表格中的数据都存储在单元格中,它是按行和列(R)(C).一些在电子表格上的操作可以应用于单个单元格(研发),而其他的可以应用于整个行或列.典型的单元操作包括插入和删除行或列和交换单元格内容.一些 ...