Spring基础知识汇总

一、Spring概述

  • ①Spring是一个开源框架

  • ②Spring为简化企业级开发而生,使用Spring开发可以将Bean对象,Dao组件对象,Service组件对象等交给Spring容器来管理,这样使得很多复杂的代码在Spring中开发却变得非常的优雅和简洁,有效的降低代码的耦合度,极大的方便项目的后期维护、升级和扩展。

  • ③Spring是一个IOC(DI)和AOP容器框架。

  • ④Spring的优良特性

    • [1]非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API
    • [2]控制反转:IOC——Inversion of Control,指的是将对象的创建权交给Spring去创建。使用Spring之前,对象的创建都是由我们自己在代码中new创建。而使用Spring之后。对象的创建都是由给了Spring框架。
    • [3]依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用setXX方法去设置,而是通过配置赋值。
    • [4]面向切面编程:Aspect Oriented Programming——AOP
    • [5]容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期
    • [6]组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。
    • [7]一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

1.1、Spring模块介绍

  • Spring框架分为四大模块

    • core核心模块。负责管理组件的Bean对象

      • spring-beans-4.0.0.RELEASE.jar
      • spring-context-4.0.0.RELEASE.jar
      • spring-core-4.0.0.RELEASE.jar
      • spring-expression-4.0.0.RELEASE.jar
    • 面向切面编程

      • spring-aop-4.0.0.RELEASE.jar
      • spring-aspects-4.0.0.RELEASE.jar
    • 数据库操作

      • spring-jdbc-4.0.0.RELEASE.jar
      • spring-orm-4.0.0.RELEASE.jar
      • spring-oxm-4.0.0.RELEASE.jar
      • spring-tx-4.0.0.RELEASE.jar
      • spring-jms-4.0.0.RELEASE.jar
    • Web模块

      • spring-web-4.0.0.RELEASE.jar
      • spring-webmvc-4.0.0.RELEASE.jar
      • spring-websocket-4.0.0.RELEASE.jar
      • spring-webmvc-portlet-4.0.0.RELEASE.jar

二、SpringIOC

  • IOC 全称指的是 Inverse Of Control 控制反转。

  • 控制反转指的是 对象的 创建 控制权的反转。

  • 在我们使用Spring之前。我们的对象创建都是由我们自己手动new出来一个对象比如:

    • BookDao bookDao = new BookDaoImpl(); 自己手动的去创建。
  • 而使用了Spring之后。对象的创建是交给Spring容器来负责。这就是控制反转。

  • 什么是DI

    • DI 指的是Dependency Injection 。是依赖注入的意思。

    • 什么是依赖注入。举个例子。

      • 在前面我们使用BookService处理业务的时候,都需要依赖BookDao去执行数据库的操作。而这个依赖的BookDao对象,是由自己代码new创建并赋值的。

      • public class BookServiceImpl implements BookService {
            private BookDao bookDao = new BookDaoImpl();
        }
        // 而在Spring中,我们只需要定义BookDao对象即可。然后把对象的赋值过程交给Spring来实现。
        public class BookServiceImpl implements BookService {
        
            private BookDao bookDao;
        
            public void setBookDao(BookDao bookDao) {
                this.bookDao = bookDao;
            }
        }
        

2.1、环境准备

2.2.1、引入Jar包

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

2.2.2、引入日志

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2.2.3、单元测试

package demo.spring;

import demo.spring.pojo.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class HelloIOC {

    @Test
    public void test1() {
        // * 1. 引入Jar包
        // * 2. 配置application核心配置
        // * 3. 获取 ApplicationContext 对象
        // * 4. 通过 ApplicationContext 获取 bean对象
        // applicationContext 就是 IOC容器
        // ClassPathXmlApplicationContext是容器的实现类
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 从容器中获取 id 为 person 定义的对象
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }
}

2.2.4、注意事项

  • 1、FileSystemXmlApplicationContext怎么用?

    • 答:new FileSystemXmlApplicationContext("src/applicationContext.xml");
  • 2、Bean是在什么时候被创建的?

  • 答:Bean在new ClassPathXmlApplicationContext的时候会被创建。

  • 3、如果调用getBean多次,会创建几个?

    • 答:默认情况下,多次调用,也只会返回同一个对象实例。
  • 4、如果在getBean的时候,传入的id不存在,就会报以下错误:

    • 答: No bean named 'person01' is defined

2.2、IOC依赖注入

2.2.1、IOC通过ID获取对象

<?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.xsd">
	<!-- 
		bean标签配置一个组件类======会由Spring容器来管理
			id 属性给bean添加唯一标识
			class 属性设置 配置的类的全类名
	 -->
	<bean id="person" class="demo.spring.pojo.Person">
		<!-- property 标签 设置 属性信息 -->
		<property name="id" value="1" />
		<property name="name" value="张三" />
		<property name="age" value="18" />
		<property name="phone" value="18688888888" />
	</bean>
</beans>
-----------------------------------------------------------------------------------
	@Test
	public void test1() {
		// applicationContext 就是 IOC容器
		// ClassPathXmlApplicationContext是容器的实现类
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		// 从容器中获取 id 为 person 定义的对象
		Person person = (Person) applicationContext.getBean("person");
		System.out.println( person );
	}

2.2.2、通过类型获取对象

  • 当applicationContext.xml配置文件中,只有一个Person.class的对象实例配置的时候,程序是可以正常运行的。

  • 常见错误

    • 当在applicationContext.xml配置文件中。有多个同Person.class类型实现的时候。
    • No qualifying bean of type [demo.spring.pojo.Person] is defined;expected single matching bean but found2;person,person02
<?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.xsd">
	<!-- 
		bean标签配置一个组件类======会由Spring容器来管理
			id 属性给bean添加唯一标识
			class 属性设置 配置的类的全类名
	 -->
	<bean id="person" class="demo.spring.pojo.Person">
		<!-- property 标签 设置 属性信息 -->
		<property name="id" value="1" />
		<property name="name" value="张三" />
		<property name="age" value="18" />
		<property name="phone" value="18688888888" />
	</bean>
	<bean id="person02" class="com.atguigu.pojo.Person">
		<!-- property 标签 设置 属性信息 -->
		<property name="id" value="2" />
		<property name="name" value="李四" />
	</bean>
</beans>
------------------------------------------------------------------------
	@Test
	public void test2() {
		// applicationContext 就是 IOC容器
		// ClassPathXmlApplicationContext是容器的实现类
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
		// 从容器中获取 id 为 person 定义的对象
		Person person = (Person) applicationContext.getBean(Person.class);
		System.out.println( person );
	}

2.2.3、通过构造方法参数名注入值

	<!-- int id, String name, int age, String phone -->
	<bean id="person03" class="demo.spring.pojo.Person">
		<!-- constructor-arg 表示有参构造方法中的一个参数 -->
		<constructor-arg name="id" value="3"></constructor-arg>
		<constructor-arg name="name" value="王五"></constructor-arg>
		<constructor-arg name="age" value="18"></constructor-arg>
		<constructor-arg name="phone" value="13666666666"></constructor-arg>
	</bean>	
	------------------------------------------
	@Test
	public void test3() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person03 = (Person) applicationContext.getBean("person03");
		System.out.println(person03);
	}

2.2.4、 index属性指定参数的位置

	<!-- int id, String name, int age, String phone -->
	<bean id="person04" class="demo.spring.pojo.Person">
		<!-- index 表示参数的索引位置。索引值从零0开始算 -->
		<constructor-arg index="0" value="4"></constructor-arg>
		<constructor-arg index="1" value="王五"></constructor-arg>
		<constructor-arg index="3" value="18610101010"></constructor-arg>
		<constructor-arg index="2" value="18"></constructor-arg>
	</bean>
	-----------------------------------------------------------
	@Test
	public void test4() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person04 = (Person) applicationContext.getBean("person04");
		System.out.println(person04);
	}

2.2.5、根据参数类型注入

	<!-- int id, String name, int age, String phone -->
	<bean id="person05" class="demo.spring.pojo.Person">
		<!-- index 表示参数的索引位置。索引值从零0开始算 -->
		<constructor-arg index="3" value="18610101010" type="java.lang.String"></constructor-arg>
		<constructor-arg index="1" value="王五" type="java.lang.String"></constructor-arg>
		<!-- 
           使用类型区分重载的构造函数
			这个地方有一点需要特别注意:
				如果代码中的类型是Integer , 那么type类型是 java.lang.Integer
				如果代码中的类型是int , 那么type类型是int
		 -->
		<constructor-arg index="2" value="18" type="int"></constructor-arg>
		<constructor-arg index="0" value="4" type="int"></constructor-arg>
	</bean>
	--------------------------------------------
	@Test
	public void test5() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person05 = (Person) applicationContext.getBean("person05");
		System.out.println(person05);
	}

2.2.6、IOC之P命名空间

<!-- p名称空间,使用很简单。 p:属性="值" -->
<bean id="person06" class="demo.spring.pojo.Person" p:id="6" p:name="第6个人" p:age="18" p:phone="18600001111" />
------------------------------
	@Test
	public void test6() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person06 = (Person) applicationContext.getBean("person06");
		System.out.println(person06);
	}

2.2.7、测试null值的使用

修改Person类的属性,添加默认值
public class Person {
	private int id;
	private String name;
	private int age;
	private String phone = "默认值";
}

	<bean id="person07" class="demo.spring.pojo.Person" p:id="7" p:age="18" p:name="第七个人">
		<property name="phone">
			<null />
		</property>
    </bean>
    
    @Test
	public void test7() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person07 = (Person) applicationContext.getBean("person07");
		System.out.println(person07);
	}

2.2.8、IOC之子对象的赋值测试

public class Car {
	private String name;
	private String carNo;

public class Person {
	private int id;
	private String name;
	private int age;
	private String phone;
	private Car car;
-------------------------------------------------	
	<!-- 定义一个车 -->
	<bean id="car" class="demo.spring.pojo.Car" p:name="宝马" p:carNo="京A12312" />
	<!--定义一个Person类 -->
	<bean id="person10" class="demo.spring.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- ref 表示引用一个对象 -->
		<property name="car" ref="car" />
	</bean>
-------------------------------------------------	
	@Test
	public void test10() {
		//创建容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person10 = (Person) applicationContext.getBean("person10");
		System.out.println(person10);
	}
	

2.2.9、IOC之内部Bean的使用

  • 内部的Bean不能被外部使用
	<bean id="person11" class="demo.spring.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- ref 表示引用一个对象 -->
		<property name="car">
			<bean id="car02" class="demo.spring.pojo.Car" p:name="保时捷" p:carNo="京B12341"></bean>
		</property>
	</bean>
	--------------------------------------
		public void test11() {
            //创建容器对象
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            Person person11 = (Person) applicationContext.getBean("person11");
            System.out.println(person11);
            System.out.println( applicationContext.getBean("car02") );			// 内部的Bean不能被外部使用
		}

2.2.10、IOC之List属性的赋值

public class Person {
	private int id;
	private String name;
	private int age;
	private String phone;
	private Car car;
	private List<String> phones;
-----------------------------------------	
<bean id="person12" class="demo.spring.pojo.Car">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- ref 表示引用一个对象 -->
		<property name="car">
			<bean id="car02" class="demo.spring.pojo.Car" p:name="保时捷"
				p:carNo="京B12341"></bean>
		</property>
		<!-- 给list集合赋值 -->
		<property name="phones">
			<list>
				<value>18611110000</value>
				<value>18611110001</value>
				<value>18611110002</value>
			</list>
		</property>
	</bean>
---------------------------------------  
	@Test
	public void test12() {
		//创建容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person12 = (Person) applicationContext.getBean("person12");
		System.out.println(person12);
	}	

2.2.11、IOC之Map属性的赋值

public class Person {
	private int id;
	private String name;
	private int age;
	private String phone;
	private Car car;
	private List<String> phones;
	private Map<String, Object> map;
	
<bean id="person13" class="demo.spring.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- ref 表示引用一个对象 -->
		<property name="car">
			<bean id="car02" class="demo.spring.pojo.Car" p:name="保时捷"
				p:carNo="京B12341"></bean>
		</property>
		<!-- map对象 -->
		<property name="map">
			<map>
				<!-- entry 表示map中有每一项 -->
				<entry key="aaa" value="aaaValue" />
				<entry key="bbb" value="bbbValue" />
				<entry key="ccc" value="cccValue" />
			</map>
		</property>
	</bean>	
	
	
	@Test
	public void test13() {
		//创建容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person13 = (Person) applicationContext.getBean("person13");
		System.out.println(person13);
	}
	

2.2.12、IOC之Properties属性的赋值

public class Person {
	private int id;
	private String name;
	private int age;
	private String phone;
	private Car car;
	private List<String> phones;
	private Map<String, Object> map;
	private Properties props;
	--------------------------------------------
	<bean id="person14" class="com.atguigu.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- map对象 -->
		<property name="props">
			<props>
				<prop key="username">root</prop>
				<prop key="password">root</prop>
				<prop key="drivers">com.mysql.jdbc.Driver</prop>
				<prop key="url">jdbc:mysql://localhost:3306/spring</prop>
			</props>
		</property>
    </bean>	
   	--------------------------------------------
   	@Test
	public void test14() {
		//创建容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person14 = (Person) applicationContext.getBean("person14");
		System.out.println(person14);
	}

2.2.13、IOC之util 名称空间

	<!-- 定义一个list集合 -->
	<util:list id="list1">
		<value>string1</value>
		<value>string2</value>
		<value>string3</value>
	</util:list>

	<bean id="person15" class="com.atguigu.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- list对象 ref表示引用 -->
		<property name="phones" ref="list1" />
	</bean>
	
	@Test
	public void test15() {
		//创建容器对象
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person15 = (Person) applicationContext.getBean("person15");
		System.out.println(person15);
		
		List<String> list = (List<String>) applicationContext.getBean("list1");
		System.out.println(list);
	}	
	

2.2.14、IOC之级联属性赋值

	<bean id="person16" class="com.atguigu.pojo.Person">
		<property name="id" value="10" />
		<property name="name" value="perosn10" />
		<property name="age" value="18" />
		<property name="phone" value="0101001" />
		<!-- list对象 ref表示引用 -->
		<property name="car"  ref="car"/>
		<!-- 级联属性 -->
		<property name="car.name" value="我的爱车"  />
	</bean>
--------------------------------
	@Test
	public void test16() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person16 = (Person) applicationContext.getBean("person16");
		System.out.println( person16 );
	}

2.2.15、IOC之静态工厂方法创建Bean

public class PersonFactory {
	public static Person createPerson() {
		Person person = new Person();
		person.setId(17);
		person.setName("这是静态工厂方法");
		return person;
	}
}
--------------------------------
<!-- 使用静态工厂方法
		class 是工厂 的全类名
		factory-method 这是工厂方法
	 -->	
<bean id="person17" class="com.atguigu.pojo.factory.PersonFactory" factory-method="createPerson" />
--------------------------------
	@Test
	public void test17() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person16 = (Person) applicationContext.getBean("person17");
		System.out.println( person16 );
	}

2.2.16、IOC之工厂实例方法创建Bean

public class PersonFactory {
	public Person getPerson() {
		Person person = new Person();
		person.setId(18);
		person.setName("这是工厂实例方法");
		return person;
	}
}
--------------------------
	<!-- 工厂实例方法分两步:
		第一步:先使用bean标签配置一个bean对象
		第二步:使用bean标签配置factory-bean和factory-method方法
	 -->
	<bean id="personFactory" class="com.atguigu.pojo.factory.PersonFactory" />
	<!-- 
		factory-bean表示使用哪一个工厂对象的实现
		factory-method表示调用对象的哪一个方法去获取对象实例
	 -->
	<bean id="person18" factory-bean="personFactory" factory-method="getPerson">
	--------------------------
	@Test
	public void test18() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person18 = (Person) applicationContext.getBean("person18");
		System.out.println( person18 );
	}	
	

2.2.17、IOC之FactoryBean接口方式

public class PersonFactoryBean implements FactoryBean<Person> {

	public Person getObject() throws Exception {
		Person person = new Person();
		person.setId(20);
		person.setName("这是PersonFactoryBean创建出来的");
		return person;
	}

	public Class<?> getObjectType() {
		return Person.class;
	}

	/**
	 * 判断是否是单例<br/>
	 * 		返回true是单例 <br/>
	 *  	返回false是多例
	 */
	public boolean isSingleton() {
		return true;
	}
}
----------------
	<!-- 使用FactoryBean接口方式创建Bean对象 -->
	<bean id="person19" class="com.atguigu.pojo.factory.PersonFactoryBean" />
	----------------
		@Test
	public void test19() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"applicationContext.xml");
		Person person19 = (Person) applicationContext.getBean("person19");
		System.out.println(person19);

		Person person191 = (Person) applicationContext.getBean("person19");
		System.out.println(person19 == person191); // true
	}

2.2.18、IOC之继承Bean配置

	<!-- 先定义一个base的 person对象 -->
	<bean id="base" class="com.atguigu.pojo.Person" p:name="basePerson" p:age="18" p:id="12312"/>
	<!-- 然后在另一个bean中。使用parent继承所有的 -->
	<bean id="person20" class="com.atguigu.pojo.Person" parent="base" p:id="20" />
	
	@Test
	public void test20() {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person20 = (Person) applicationContext.getBean("person20");
		System.out.println(person20);
		
		System.out.println( "这是base的---" + applicationContext.getBean("base") );
	}

2.2.19、IOC之组件创建顺序

public class A {
	public A() {
		System.out.println("A 被创建了");
	}
}
public class B {
	public B() {
		System.out.println("B 被创建了");
	}
}
public class C {
	public C() {
		System.out.println("C 被创建了");
	}
}
----------------------
<!-- 默认情况下。bean对象创建的顺序,是从上到下
			depends-on 可以设定依赖
	 -->
	<bean id="a" class="com.atguigu.pojo.A" depends-on="b,c"/>
	<bean id="b" class="com.atguigu.pojo.B" />
	<bean id="c" class="com.atguigu.pojo.C" />
----------------------------
	@Test
	public void test1() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
	}

2.2.20、基于xml配置文件的自动注入

public class Car {
	private String carNo;
	private String name;

public class Person {

	private Car car;
	public Person(Car car) {
		this.car = car;
	}
-----------
	<bean id="car1" class="com.atguigu.pojo.Car">
		<property name="carNo" value="京B23412" />
		<property name="name" value="劳死来死"/>
	</bean>
	<bean id="car2" class="com.atguigu.pojo.Car">
		<property name="carNo" value="京B23412" />
		<property name="name" value="劳死来死2"/>
	</bean>
	<!-- 
		autowire 属性设置是否自动查找bean对象并给子对象赋值
		
		default 和 no 表示不自动查找并注入(你不赋值,它就null)
		byName 	是指通过属性名做为id来查找bean对象,并注入
					1、找到就注入
					2、找不到就为null
		byType  是指按属性的类型进行查找并注入
					1、找到一个就注入
					2、找到多个就报错
					3、没有找到就为null
		constructor 是指按构造器参数进行查找并注入。
					1、先按照构造器参数类型进行查找并注入
					2、如果按类型查找到多个,接着按参数名做为id继续查找并注入。
					3、按id查找不到,就不赋值。
	 -->
	<bean id="p19" class="com.atguigu.pojo.Person" autowire="constructor">
		<property name="name" value="p19" />
	</bean>
	

2.2.21、IOC之Bean的单例和多例(重点)

	<!-- 
		scope 属性设置对象的域
			singleton			表示单例(默认)
								1、Spring容器在创建的时候,就会创建Bean对象
								2、每次调用getBean都返回spring容器中的唯一一个对象
								
			prototype			表示多例
								1、多例在Spring容器被创建的时候,不会跟着一起被创建。
								2、每次调用getBean都会创建一个新对象返回
								
			request				在一次请求中,多次调用getBean方法都是返回同一个实例。
								getBean("p20"); 底层大概的实现原理
								Object bean = request.getAttribute("p20");
								if (bean == null) {
									bean = new 对象();
									request.setAttribute("p20",bean);
								}
								return bean;
								
								
			session				在一个会话中,多次调用getBean方法都是返回同一个实例。
								getBean("p20"); 底层大概的实现原理
								Object bean = session.getAttribute("p20");
								if (bean == null) {
									bean = new 对象();
									session.setAttribute("p20",bean);
								}
								return bean;
	 -->
	<bean id="p20" class="com.atguigu.pojo.Person" scope="singleton">
		<property name="name" value="p20" />
	</bean>
	----------------------
	@Test
	public void test3() throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		System.out.println( applicationContext.getBean("p20") );
		System.out.println( applicationContext.getBean("p20") );
		System.out.println( applicationContext.getBean("p20") );
		System.out.println( applicationContext.getBean("p20") );			// 单例模式得出都一样
	}
	

2.3、IOC生命周期

	<!-- 
		init-method配置初始化方法(bean对象创建之后)
		destroy-method配置销毁方法(在spring容器关闭的时候,只对单例有效)
	 -->
	<bean id="p21" class="com.atguigu.pojo.Person" init-method="init" destroy-method="destroy" scope="singleton">
		<property name="name" value="p21"/>
	</bean>
	------------------------------
	@Test
	public void test4() throws Exception {
		ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		applicationContext.getBean("p21");
		applicationContext.close();
	}

单例的bean,生命周期有11个步骤:

  • 1.instantiate bean对象实例化,bean对象实例化,是在加载配置文件的时候实例的。即,我们启动spring容器的时候,加载配置文件,此时就实例化bean了。
  • 2.populate properties 封装属性
  • 3.如果Bean实现BeanNameAware, 执行 setBeanName
  • 4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware,设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
  • 5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization(此点常常用来增强bean)
  • 6.如果Bean实现InitializingBean 执行 afterPropertiesSet
  • 7.调用 指定初始化方法 init
  • 8.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessAfterInitialization(此点常常用来增强bean)
  • 9.执行业务处理
  • 10.如果Bean实现 DisposableBean 执行 destroy
  • 11.调用 指定销毁方法

`

上一篇:SpringIoC&DI


下一篇:函数笔记.