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

2023-05-16

前提:

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>

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • OSCP-Nickel(爆破pdf、本地http提权)

    目录 扫描 HTTP 提权 扫描 FileZilla不接受匿名FTP登录 端口21上的SSH和3389上的RDP很少是初始入口点 但是如果遇到一些凭据 可以记住这一点 HTTP 打开Web浏览器并导航到端口8089和3333 用于的HTTP
  • 爆破pdf文件

    安装 apt install pdfcrack 使用 f xff1a 指定被爆破的pdf文件 w xff1a 爆破字典 pdfchack f indesk pdf w rockyou txt
  • 解决Ubuntu 16.04 的应用商店卸载或加载不出来的教程

    ubuntu软件中心偶尔打不开 xff0c 虽然是小问题 xff0c 不过却是为这些头疼 有的时候加载不出来 xff0c 先用下面的试试 sudo apt install python apt 如果不行 xff0c 继续下面的方法 打开终端
  • OSCP-Nappa(修改web源码打开注释、base32)

    目录 扫描 FTP WEB 提权 扫描 FTP 允许匿名ftp 查看共享文件夹中的内容 nbsp 这里有很多文件 无法在某些文件中找到直接凭据 继续枚举端口8080上的Web服务 可以从索引页中列举出许多用户 WEB
  • Linux系统用户下的 .bashrc 文件

    目录 介绍 修改 bashrc进行个性化设置 实例1 实例2 介绍 程序文件 这个文件主要保存个人的一些个性化设置 xff0c 如命令别名 路径等 也即在同一个服务器上 xff0c 只对某个用户的个性化设置相关 bashrc 为每一个运行b
  • curl 上传webshell到web目录

    目录 环境 curl上传文件 结果 环境 curl上传文件 cat codeexec php lt php system GET 39 cmd 39 gt curl T cocdeexec php u 39 admin admin 39 h
  • MSSQL注入利用xp_cmdshell执行命令(细)

    目录 介绍 检查我们是否可以堆叠查询 检查权限 阅读命令输出 扩展 介绍 与MySQL不同 MSSQL提供了xp cmdshell 它允许我们执行系统命令 在xp cmdshell中 大多数时候我们都有特权使
  • ssh私钥爆破(Enter passphrase for key )

    环境背景 1 有私钥 2 登录还是询问密码 3 改成600 使用的时候提示Enter passphrase for key 解决方法 1 用john爆破私钥的passphrase 2 ssh2john key gt hash 3 然后joh
  • digitalworld.local: JOY(ftp将可读文件夹上传到可写文件夹)

    目录 扫描 FTP 提权 扫描 sudo nmap sC sV T4 v O 192 168 1 183 o nmap Nmap scan report for JOY wlan 192 168 1 183 Host is up 0 000
  • symfonos 1(smtp注入webshell,配合文件文件包含)

    目录 扫描 SMB 提权 扫描 SMB 让我们使用SMBMAP检查这些目录的权限 smbmap d workgroup H www example com 可能 匿名帐户可访问 使用smb尝试连接共享网络以访问 anonymous目录 sm
  • symfonos 2

    目录 扫描 SMB SSH nbsp 提权 扫描 由于端口80是打开的 我们试图在浏览器中打开IP地址 但在网页上没有找到任何有用的信息 我们还尝试了dirb和其他目录暴力工具 但没有找到任何东西 SMB 为了进一步枚举 我们使用Enum4
  • Metasploit渗透测试:工作区使用帮助

    目录 编辑 help 查看工作区 添加工作区 显示工作区详情
  • 生成密码字典(特殊字符)

    目录 配置字典规则 含义 生成字典 特殊字符表 配置字典规则 打开john路径 nbsp cat etc john john conf 在 List Rules Wordlist 下添加 0 9 0 9 0 9 0 9 amp lt gt
  • Ubuntu系统下卸载命令apt-get remove/purge/autoremove/clean/autoclean的区别

    1 特意提醒新手注意一下 xff0c 下面的在桌面版的Ubuntu系统下尽量不要使用 xff1a apt get autoremove 删除已安装的软件包 xff08 保留配置文件 xff09 xff0c 不会删除依赖软件包 xff0c 且
  • FTP Entering Extended Passive Mode

    目录 原因 两种方法解决 哪个行用哪种 方法一 方法二 原因 FTP的连接建立有两种模式PORT
  • windows文件传输到linux

    Windows上传使用Windows脚本语言 在某些情况下 我们可能需要使用Windows客户端从目标网络中泄漏数据 这可能很复杂 因为Windows上默认很少启用标准的TFTP FTP和HTTP服务器 幸运的是 如果允许出站HTTP流量
  • 下载后直接运行ps1脚本(脚本文件不存入本地硬盘)

    kali 64 kali var www html sudo cat helloworld ps1 Write Output 34 Hello World 34 C Users Offsec gt powershell exe IEX Ne
  • Linux安装FTP服务(Pure-FTPd)

    目录 介绍 安装 客户端使用 介绍 攻击机器上快速安装Pure FTPd服务器 如果您已经在Kali系统上配置了FTP服务器 则可以跳过这些步骤 安装 kali kali sudo apt update amp amp sudo apt i
  • 环形缓存队列

    单片机开发中经常碰到需要用到缓存的地方 xff0c 例如串口 xff0c DMA等设备工作时 xff0c 下面介绍一种简单的环形缓存队列 定义数据结构 span class token keyword typedef span span c
  • Spring笔记(一):Ioc 之 Bean的管理

    前提 xff1a 1 需要 spring dom4j junit commons logging等的jar包 xff0c 配置web xml xff0c 新增 applicationContext xml 2 Spring主要核心是 xff