Spring笔记(一):Ioc 之 Bean的管理

前提:

1、需要 spring、dom4j、junit、commons-logging等的jar包, 配置web.xml,新增 applicationContext.xml

2、Spring主要核心是:

1)控制反转(IOC):以前传统的java开发模式中,当需要一个对象时我们,我们会自己使用new或者getInstance等直接或者间接调用构造方法创建一个对象,而在Spring开发模式中,Spring容器使用了工厂模式为我们创建了所需要的对象,我们使用时不需要自己去创建,直接调用Spring为我们提供的对象即可,这就是控制反转的思想。实例化一个java对象有三种方式:使用类构造器,使用静态工厂方法,使用实例工厂方法,当使用spring时我们就不需要关心通过何种方式实例化一个对象,spring通过控制反转机制自动为我们实例化一个对象。

2)依赖注入(DI):Spring使用java Bean对象的Set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程就是依赖注入的基本思想。

3)面向切面编程(AOP):在面向对象编程(OOP)思想中,我们将事物纵向抽象成一个个的对象。而在面向切面编程中,我们将一个个对象某些类似的方面横向抽象成一个切面,对这个切面进行一些如权限验证,事物管理,记录日志等公用操作处理的过程就是面向切面编程的思想。

一、Spring的 Ioc 简介

(一)Spring容器管理Bean

1、创建Bean :接口和实现类

<span style="font-family:Arial;font-size:18px;">package main.java.com.spring.ioc.base.service;

/**
 *
 * PersonService
 *
 * @desc
 * @author SAM-SHO
 * @Dec 25, 2014
 */
public interface PersonService {
	public void save();
}
</span>
<span style="font-family:Arial;font-size:18px;">/**
 *
 */
package main.java.com.spring.ioc.base.service.impl;

import main.java.com.spring.ioc.base.service.PersonService;

/**
 * PersonServiceImpl
 * @desc
 * @author SAM-SHO
 * @Dec 25, 2014
 */
public class PersonServiceImpl implements PersonService {

	public PersonServiceImpl() {
		System.out.println("我被实例化了");
	}

	@Override
	public void save() {
		System.out.println("我是 save() 方法");

	}

	/**
	 * 初始化方法
	 */
	public void init(){
		System.out.println("我是初始化方法");
	}

	/**
	 * 销毁方法
	 */
	public void destroy(){
		System.out.println("我是销毁方法,关闭资源");
	}

}
</span>

2、配置文件:

1)在 applicationContext.xml 配置文件中引入Bean 的xml schema。

2)管理Bean :<bean>标签

<span style="font-family:Arial;font-size:18px;">	<!-- name与id功能一直,但是id为xml的默认属性可以校验,而name则可以取一些特殊符号的名字如 。。。?aa? -->
	<!-- 这样配置好后,会交由spring创建和管理,我们只需要去spring容器中获取 -->
	<bean id="personServiceImpl" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

3、测试:

<span style="font-family:Arial;font-size:18px;">//		ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		tPersonService.save(); //【输出】我是 save() 方法
</span>

(二)Spring管理Bean的原理

1、自定义容器类

<span style="font-family:Arial;font-size:18px;">package test.java.com.spring.ioc.base;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;

/**
 *
 * MyClassPathXMLApplicationContext
 *
 * @title 自定义容器
 * @desc
 * @author SAM-SHO
 * @Dec 25, 2014
 */
public class MyClassPathXMLApplicationContext {
	private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	private Map<String, Object> sigletons = new HashMap<String, Object>();

	public MyClassPathXMLApplicationContext(String filename) {
		this.readXML(filename);
		this.instanceBeans();
	}

	/**
	 * 反射,完成bean的实例化
	 */
	private void instanceBeans() {
		for (BeanDefinition beanDefinition : beanDefines) {
			try {
				if (beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim()))
					sigletons.put(beanDefinition.getId(), Class.forName(beanDefinition.getClassName()).newInstance());
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 读取xml配置文件
	 *
	 * @param filename
	 */
	private void readXML(String filename) {
		SAXReader saxReader = new SAXReader();
		Document document = null;
		try {
			URL xmlpath = this.getClass().getClassLoader().getResource(filename);
			document = saxReader.read(xmlpath);
			Map<String, String> nsMap = new HashMap<String, String>();
			nsMap.put("ns", "http://www.springframework.org/schema/beans");// 加入命名空间
			XPath xsub = document.createXPath("//ns:beans/ns:bean");// 创建beans/bean查询路径
			xsub.setNamespaceURIs(nsMap);// 设置命名空间
			List<Element> beans = xsub.selectNodes(document);// 获取文档下所有bean节点
			for (Element element : beans) {
				String id = element.attributeValue("id");// 获取id属性值
				String clazz = element.attributeValue("class"); // 获取class属性值
				BeanDefinition beanDefine = new BeanDefinition(id, clazz);
				beanDefines.add(beanDefine);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取bean实例
	 *
	 * @param beanName
	 * @return
	 */
	public Object getBean(String beanName) {
		return this.sigletons.get(beanName);
	}
}
</span>

2、自定义DTO,数据传输类:

<span style="font-family:Arial;font-size:18px;">package test.java.com.spring.ioc.base;

/**
 *
 * BeanDefinition
 * @title Bean对象
 * @desc
 * @author SAM-SHO
 * @Dec 25, 2014
 */
public class BeanDefinition {
	private String id;//id属性
	private String className;//class属性

	public BeanDefinition(String id, String className) {
		this.id = id;
		this.className = className;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}

}
</span>

3、测试:使用自定义的容器管理Bean的初始化

<span style="font-family:Arial;font-size:18px;">	//初始化spring容器
	@Test
	public void instanceSpring() {

//		ApplicationContext cxt = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		tPersonService.save(); //【输出】我是 save() 方法

		//自定义获取Bean
		MyClassPathXMLApplicationContext mcxt = new MyClassPathXMLApplicationContext("applicationContext.xml");
		tPersonService = (PersonService) mcxt.getBean("personServiceImpl");
		tPersonService.save();//【输出】我是 save() 方法
	}
</span>

二、Spring的三种实例化Bean的方式

(一)类构造器实例化Bean,常用,即上面的实例。

1、对应的代码类为:

<span style="font-family:Arial;font-size:18px;">public class PersonServiceImpl implements PersonService {

	public PersonServiceImpl() {
		System.out.println("我被实例化了");
	}

	@Override
	public void save() {
		System.out.println("我是 save() 方法");

	}
}</span>

2、配置文件配置:

<span style="font-family:Arial;font-size:18px;">	<!-- 1-1类构造器实例化Bean -->
	<!-- name与id功能一直,但是id为xml的默认属性可以校验,而name则可以取一些特殊符号的名字如 。。。?aa? -->
	<!-- 这样配置好后,会交由spring创建和管理,我们只需要去spring容器中获取 -->
	<bean id="personServiceImpl" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

(二)静态工厂方法实例化Bean

1、对应的代码类为:创建工厂类,新建静态方法。

<span style="font-family:Arial;font-size:18px;">/**
 *
 * PersonServiceFactory
 * @title 工厂类
 * @desc 静态工厂方法实例化Bean
 * @author SAM-SHO
 * @Dec 26, 2014
 */
public class PersonServiceFactory {

	/**
	 * 静态方法,创建 PersonServiceImpl 对象
	 * @return
	 */
	public static PersonServiceImpl createPersonService(){

		return new PersonServiceImpl();
	}
}</span>

2、配置文件配置:factory-method="createPersonService"

<span style="font-family:Arial;font-size:18px;">	<!-- 1-2静态工厂方法实例化Bean -->
	<bean id="personServiceImpl2"  class="main.java.com.spring.ioc.base.service.impl.PersonServiceFactory"
		factory-method="createPersonService" >
	</bean>
</span>

(三)实例工厂方法实例化Bean,配置的时候,先实例化工厂类。

1、对应的代码类为:在工厂类中新增非静态方法

<span style="font-family:Arial;font-size:18px;">
	/**
	 * 非静态的方法,创建PersonServiceImpl 对象
	 * @return
	 */
	public PersonServiceImpl createPersonService2(){

		return new PersonServiceImpl();
	}
</span>

2、配置文件配置:非静态方法的调用,需先实例化工厂类。factory-bean 和 factory-method

<span style="font-family:Arial;font-size:18px;">	<!-- 1-3实例工厂方法实例化Bean  -->
	<!-- 先实例化工厂类,然后在实例化需要的Bean -->
	<bean id="personServiceFactory" class="main.java.com.spring.ioc.base.service.impl.PersonServiceFactory"></bean>
	<bean id="personServiceImpl3" factory-bean="personServiceFactory" factory-method="createPersonService2"></bean>
</span>

(四)测试:

<span style="font-family:Arial;font-size:18px;">	//Spring的三种实例化Bean的方式
	@Test
	public void ManageBean3Mothed() {

		// 1-类构造器实例化Bean,常用
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		tPersonService.save(); //【输出】我是 save() 方法

		// 2-静态工厂方法实例化Bean
		PersonService tPersonService2 = cxt.getBean("personServiceImpl2", PersonServiceImpl.class);//利用接口接收
		tPersonService2.save(); //【输出】我是 save() 方法

		// 3-实例工厂方法实例化Bean,配置的时候,先实例化工厂类
		PersonService tPersonService3 = cxt.getBean("personServiceImpl3", PersonServiceImpl.class);//利用接口接收
		tPersonService3.save(); //【输出】我是 save() 方法
	}
</span>

三、Spring管理的Bean的作用域 Scope

(一)测试spring容器创建对象的实例个数。

1、配置文件:

<span style="font-family:Arial;font-size:18px;">	<bean id="personServiceImpl" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2、测试代码:true,说明是单例,同一个对象。

<span style="font-family:Arial;font-size:18px;">		// 1-查看Bean对象的实例
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		PersonService tPersonService2 = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		System.out.println(tPersonService==tPersonService2);//【输出】true,说明是单例
</span>

(二)Bean的作用域 Scope:默认在每个spring Ioc容器中一个bean定义只有一个对象实例。

1、Scope的取值:

1)singleton:默认,单例。

2)prototype:每次都是新的。管理struts的action,一定要是prototype。

3)request、session、global session。

2、配置 scope="prototype"

1)配置文件:

<span style="font-family:Arial;font-size:18px;">	<!-- 2-Bean的作用域  -->
	<bean id="personServiceImpl4" scope="prototype"  class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2)测试代码:

<span style="font-family:Arial;font-size:18px;">	// Spring管理的bean的作用域
	@Test
	public void ManageBeanScope() {

		// 1-查看Bean对象的实例
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		PersonService tPersonService2 = cxt.getBean("personServiceImpl", PersonServiceImpl.class);//利用接口接收
		System.out.println(tPersonService==tPersonService2);//【输出】true,说明是单例

		/*
		 * 2-Bean的作用域 Scope:在每个spring Ioc容器中一个bean定义只有一个对象实例。
		 * singleton:默认,单例
		 * prototype:每次都是新的
		 * request
		 * session
		 * global session
		 */
		// 配置 	<bean id="personServiceImpl4" scope="prototype"  class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl"></bean>
		PersonService tPersonService4 = cxt.getBean("personServiceImpl4", PersonServiceImpl.class);//利用接口接收
		PersonService tPersonService4_1 = cxt.getBean("personServiceImpl4", PersonServiceImpl.class);//利用接口接收
		System.out.println(tPersonService4==tPersonService4_1);//【输出】false,说明是每次都是新的对象

	}
</span>

四、Spring管理的Bean的生命周期

1、默认情况下会在容器启动时初始化Bean,但是,当Scope = "prototype"的时候,Bean只会在getBean()方法的时候实例化。

2、可以指定Bean节点的lazy-init="true" 来延迟初始化Bean,这时候,只有第一次获取Bean 时才会初始化Bean,<bean lazy-init="true"。

3、如果想对所有bean 都应用延迟初始化,可以在根节点<beans default-lazy-init="true"> 。

4、init-method="" 指定初始化方法;destroy-method="" 指定销毁方法

(一)默认初始化:

1、默认为容器启动时初始化Bean。

1)配置:

<span style="font-family:Arial;font-size:18px;">	<bean id="personServiceImpl" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2)测试代码:初始化容器即可

<span style="font-family:Arial;font-size:18px;">ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");</span>

3)【输出】:PersonServiceImpl构造方法中的输出:我被实例化了

2、Scope = "prototype" 的例外

1)配置:

<span style="font-family:Arial;font-size:18px;">	<bean id="personServiceImpl" scope="prototype" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2)测试:需要在getBean()的时候才会实例化

<span style="font-family:Arial;font-size:18px;">		//1-默认:这边容器启动的时候就会对Bean实例化
		//但是,当Scope = "prototype"的时候,Bean只会在getBean()方法的时候实例化
//		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
</span>

(二)懒加载初始化:lazy-init="true"

1、配置文件:

<span style="font-family:Arial;font-size:18px;">	<!-- 3-Bean 的生命周期: lazy-init="true"延迟初始化  -->
	<bean id="personServiceImpl5" lazy-init="true"  class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2、测试代码:本来是初始化的时候即会实例化,但是只有调用getBean()的时候才会实例化。

<span style="font-family:Arial;font-size:18px;">// 2-使用lazy-init="true",延迟初始化
ApplicationContext cxt2 = new ClassPathXmlApplicationContext("applicationContext.xml");
PersonService tPersonService5 = cxt2.getBean("personServiceImpl5", PersonServiceImpl.class);//利用接口接收
</span>

(三)指定初始化与销毁方法:init-method="" ;destroy-method=""

1、配置文件:指定Bean中初始化与销毁的方法名称。

<span style="font-family:Arial;font-size:18px;">	<!-- init-method="" 指定初始化方法 destroy-method="" 指定销毁方法 -->
	<bean id="personServiceImpl6" init-method="init" destroy-method="destroy" class="main.java.com.spring.ioc.base.service.impl.PersonServiceImpl">
	</bean>
</span>

2、测试代码:

1)init-method="":初始化。

<span style="font-family:Arial;font-size:18px;">		// 3-init-method="" 指定初始化方法。先实例化,再调用初始化方法
		ApplicationContext cxt3 = new ClassPathXmlApplicationContext("applicationContext.xml");
		PersonService tPersonService6 = cxt3.getBean("personServiceImpl6", PersonServiceImpl.class);//【输出】我是初始化方法
</span>

2)destroy-method="" :销毁方法。

<span style="font-family:Arial;font-size:18px;">		// 4-destroy-method="" 指定销毁方法
		// AbstractApplicationContext 正常关闭容器
		AbstractApplicationContext cxt4 = new ClassPathXmlApplicationContext("applicationContext.xml");
		cxt4.close();//【输出】 我是销毁方法,关闭资源
</span>

时间: 2024-07-29 07:30:36

Spring笔记(一):Ioc 之 Bean的管理的相关文章

Spring笔记(4)-----&lt;bean&gt;的基本配置

Spring容器成功需要具备的三个条件: 1)Spring框架的类包都已经放在应用程序的类路径下. 2)应用程序为Spring提供了完备的Bean配置信息. 3)Bean的类都已经放在类路径下. Spring启动时读取应用程序的Bean配置信息,在容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配好Bean的依赖关系,为上层应用提供准备就绪的运行环境. Bean的配置信息是Bean的元数据信息,有4部分: 1)Bean的实现类. 2)Bean的属性信息. 3)Bean

spring的配置介绍和bean的管理方式

前言 不管说什么框架,我们总是难以逃脱该框架的配置文件,所以接下来我们就要讲述一下spring的配置文件的相关标签的配置,另外会介绍一下spring的bean的管理方式(XML文件中). spring的配置 id属性和name属性 id:给bean起个名字,在约束中采用 ID 的约束,唯一,必须以字母开始,可以使用字母.数字.连字符.下划线.句话.冒号,不能出现特殊字符. <bean id=”bookAction”> name:给bean起个名字,没有采用 ID 的约束.name出现特殊字符,

Spring笔记——6.容器中bean的生命周期

spring可以管理单例bean的生命周期,知道何时被创建,核实初始化,何时销毁,也可以进行某些通用资源申请,销毁前资源回收.对于prototype,容器只负责创建,之后就撒手不管自生自灭.容器不知道一共创建了多少prototype,也不知道他们什么时候会被销毁,所以容器没法管理prototype. 管理bean的生命周期有如下两个时机: 注入依赖关系后 即将销毁bean前 依赖关系注入后的行为 通过设定init-method属性指定某个方法或者实现InitializingBean接口指定需要实

Spring(一):概述,IOC(Bean管理),整合Web项目,整合JUnit单元测试

1 Spring框架的学习路线 Spring第一天:IOC容器(Bean管理),Spring与Web项目整合 Spring第二天:AOP(面向切面编程),Spring的JDBC模板 Spring第三天:Spring的事务管理,SSH整合开发 2 Spring的框架概述 2.1 什么是Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and

Spring核心技术之IOC容器(一):IOC容器与Bean简介

最近开始研究Spring框架,今天学习Spring的核心内容IOC 与 Bean 1. Spring IOC 与 Bean 简介  Inversion of Control (IoC)即控制反转,也叫dependency injection (DI)依赖注入,Spring实现了一个基于配置文件的复杂工厂模式来提供实现控制反转. org.springframework.beans 和org.springframework.context包是Spring中实现IOC的基础包,其中BeanFactor

【Spring源码--IOC容器的实现】(五)Bean对象的创建

前言: 1.第一次直接用CSDN原生的编辑器写博客,格式排版还有点陌生,见谅. 2.前面的文章我们写了IOC容器的启动,也就是把xml里面的配置都解析成Spring的内部结构BeanDefinition,并存储在Spring的容器中.下面我们将分析IOC容器室怎样对bean的依赖关系进行注入的.依赖注入的过程是第一次向IOC容器索要bean时触发的(例外:lazy-init实现bean的预实例化),也就是getBean方法. 3.依赖注入可以分为两个过程,一是bean所包含的Java对象的创建,

Spring学习之路(三)bean注解管理AOP操作

在类上面.方法上面.属性上面添加注解:并用bean来管理: 书写方法:@注解名称(属性名称=值) 第一步:导入jar包 导入spring-aop.jar(spring注解包): 第二步:创建实体类(注解对象) package com.aop; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; /** * value的值是自定义属性值 * @Co

Spring学习笔记1——IOC: 尽量使用注解以及java代码(转)

在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目. 预想的基本流程如下: 1.用户网站注册,填写用户名.密码.email.手机号信息,后台存入数据库后返回ok.(学习IOC,mybatis,SpringMVC的基础知识,表单数据验证,文件上传等) 2.服务器异步发送邮件给注册用户.(学习消息队列) 3.用户登录.(学习缓存.Spring Security) 4.其他. 边学习边总结,不定时更新.项目环境为Intellij + Spring4. 一.准备工作. 1.m

Spring学习笔记1——IOC: 尽量使用注解以及java代码

在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目. 预想的基本流程如下: 1.用户网站注册,填写用户名.密码.email.手机号信息,后台存入数据库后返回ok.(学习IOC,mybatis,SpringMVC的基础知识,表单数据验证,文件上传等) 2.服务器异步发送邮件给注册用户.(学习消息队列) 3.用户登录.(学习缓存.Spring Security) 4.其他. 边学习边总结,不定时更新.项目环境为Intellij + Spring4. 一.准备工作. 1.m