bean标签和管理对象的细节

bean标签

	/**
	属性:
	id:给对象在容器中提供一个唯一标识。用于获取对象。
	class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
	scope:指定对象的作用范围。
		- singleton:单例,默认的,在SpringIOC容器中仅仅存在一个bean的实例。
		- prototype:原型,表示bean的每个实例都是唯一的,也就是每一次获取相同的bean,IOC容器都会重新实例化一个。
		- request:请求域 每次的http请求都会创建一个新的bean的实例
		- session:会话域,同一个Http session共享一个bean,不同的Http session则是不同的bean
	init-method:指定类中的初始化方法名称。
	destroy-method:指定类中销毁方法名称。
	**/
	<bean id="person" class="com.wanee.bean.Person" scope="prototype" init-method="init" destroy-method="destory">
		<property name="age" value="20"></property>
		<property name="name" value="青霞仙子"></property>
	</bean>

bean 的作用范围和生命周期

单例对象:scope=“singleton”
一个应用只有一个对象的实例。它的作用范围就是整个引用。
生命周期:
对象出生:当应用加载,创建容器时,对象就被创建了。
对象活着:只要容器在,对象一直活着。
对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
多例对象:scope=“prototype”
每次访问对象时,都会重新创建对象实例。
生命周期:
对象出生:当使用对象时,创建新的对象实例。
对象活着:只要对象在使用中,就一直活着。
对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了。

实例化 Bean 的三种方式

  • 使用默认无参构造函数(常用)
<!--在默认情况下:
	它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。
-->
<bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl"/>
  • spring 管理静态工厂- 使用静态工厂的方法创建对象
    调用静态方式方法创建bean是将对象的创建的过程封装到静态方法中,当客户端需要对象是,只需要简单的调用静态方法,而不关系对象创建的细节
    要声明通过静态方式创建bean,需要在bean的class属性中指拥有该工厂的方式的类,同时在Factory-method属性中,指定工厂方法名称, 最后使用标签为方法传递参数。
    创建静态工厂类
public class StaticFactory {

	//定义静态属性Map
	private static Map<String,Car> cars = new HashMap<>();
	
	//定义静态块
	static {
		cars.put("小一", new Car("Bnze","white",500000.0));
		cars.put("小二", new Car("BMW","black",500000.0));
		cars.put("小三", new Car("Audi","red",500000.0));
	}
	
	//定义静态方法:通过key取得Car对象
	public static Car getCar(String key) {
		return cars.get(key);
	}
	
	//直接获取对象
	public static Car createCar(){
		return new Car('BYD','blue',5000.0);
	}
}

配置bean

<!-- 
		要声明通过静态方式创建bean,需要在bean的class属性中指拥有该工厂的方式的类,
		同时在factory-method属性中,指定工厂方法名称, 最后使用<constructor-arg>元素为方法传递参数
		
		id:配置的bean实际上就是我们要获取的bean
		class:注意配置的不是要获取的bean的全类名,而是工厂方式的全类名
		factory-method:配置的是静态工厂方法名称,即获取bean的方法名称
		constructor-arg:如果静态工厂方法有入参,则使用此标签传递
	 -->
	<bean id="car" class="com.wanee.factorymehodandfactorybean.StaticFactory" factory-method="getCar">
		<constructor-arg value="小三"></constructor-arg>
	</bean>
	<!-- 无参 -->
	<bean id="car1" class="com.wanee.factorymehodandfactorybean.StaticFactory" factory-method="createCar"> </bean>
</beans>
  • spring 管理实例工厂-使用实例工厂的方法创建对象
    ① 创建实例工厂
public class StaticFactory {

	//定义静态属性Map
	private static Map<String,Car> cars = new HashMap<>();
	
	//定义静态块
	static {
		cars.put("小一", new Car("Bnze","white",500000.0));
		cars.put("小二", new Car("BMW","black",500000.0));
		cars.put("小三", new Car("Audi","red",500000.0));
	}
	
	//定义静态方法:通过key取得Car对象
	public static Car getCar(String key) {
		return cars.get(key);
	}
	
	//直接获取对象
	public static Car createCar(){
		return new Car('BYD','blue',5000.0);
	}
}

② 配置bean

<!-- 
		实例工厂本身是需要配置到IOC容器中
		factory-bean : 引用实例工厂的bean
		factory-method:配置的是实例工厂中获取bean的方法名称
		constructor-arg 标签: 如果实例工厂方法中获取bean的名称的方法有参数,则使用此标签传递
	 -->
	 <bean id="instanceFactory" class="com.wanbangee.factorymehodandfactorybean.InstanceFactory"></bean>
	 <bean id="car1" factory-bean="instanceFactory" factory-method="getCar">
	 	<constructor-arg value="小二"></constructor-arg>
	 </bean>
	 <!-- 无参 -->
	 <bean id="car2" factory-bean="instanceFactory" factory-method="createCar"> </bean>

依赖注入

  • 概念

依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。
我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc解耦只是降低他们的依赖关系,但不会消除。
例如:我们的业务层仍会调用持久层的方法。 那这种业务层和持久层的依赖关系,在使用 spring之后,就让 spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

  • 属性注入
    属性注入也叫做setter注入,意味着通过setter方法进行属性的注入。
<bean id="person" class="com.wanee.di.Person">
		<!-- 
			使用property标签完成属性注入
				name : javaBean风格的属性名,就是setter方法对应的属性名
				value 或者value标签: 给属性设置的字面值[String,基本数据类型]
				ref 或者ref标签: 表示引用其他的bean
		 -->
		<property name="age" value="19"></property>
		<property name="name">
			<value>白骨精</value>
		</property>
		<property name="car">
			<ref bean="car"/>
		</property>
	</bean>
	
	<bean id="car" class="com.wanee.di.Car">
		<property name="barnd" value="BMW"></property>
		<property name="price" value="350000"></property>
	</bean>
	
</beans>

配置的bean的class属性为全类名,默认情况下,会调用类中无参数的构造器,假如无参数的构造器不存在,也没有属性对应的getter和setter方法,只有有参数构造器,那么则默认的构造对象的构造器就不能执行,而且属性注入也不能成功。那么我们只能够针对有参数的构造器完成bean的实例化操作。

  • 构造注入

使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置
的方式,让 spring 框架来为我们注入。

<!-- 使用构造注入 
		public Car(String barnd, String color, Integer maxSpeed, Double price)
	-->
	<bean id="car" class="com.wanee.di.Car">
		<constructor-arg value="Audi"></constructor-arg>
		<constructor-arg value="black"></constructor-arg>
		<constructor-arg value="220"></constructor-arg>
		<constructor-arg value="300000"></constructor-arg>

存在问题:比如参数传递的时候,顺序没有按照构造的入参顺序编写?
如下:

<!-- 使用构造注入 
		public Car(String barnd, String color, Integer maxSpeed, Double price)
	-->
	<bean id="car" class="com.wanee.di.Car">
		<constructor-arg value="black"></constructor-arg>
		<constructor-arg value="Audi"></constructor-arg>
		<constructor-arg value="300000"></constructor-arg>
		<constructor-arg value="220"></constructor-arg>
	</bean>

这个时候存在的问题,就是品牌和颜色,最高时速和价格位置乱了, 导致构造的对象不正确,那么我们可以通过index属性设置参数的顺序。

<!-- 使用构造注入 
		public Car(String barnd, String color, Integer maxSpeed, Double price)
		- index:通过index属性可以设置构造注入传入参数的顺序,从0开始到参数个数-1结束
	-->
	<bean id="car" class="com.wanee.di.Car">
		<constructor-arg value="black" index="1"></constructor-arg>
		<constructor-arg value="Audi" index="0"></constructor-arg>
		<constructor-arg value="300000" index="3"></constructor-arg>
		<constructor-arg value="220" index="2"></constructor-arg>
	</bean>

还存在问题:
如果类中有多个构造器存在,则会根据传入参数的个数找到相匹配的构造器执行。现在我们继续修改Car这个类,添加两个有三个参数的构造器?
可以通过name属性指定参数在构造函数中的名称或type属性指定参数在构造函数中的数据类型

	<bean id="car2" class="com.wanee.di.Car">
		<constructor-arg value="Audi" index="0" type="java.lang.String"></constructor-arg>
		<constructor-arg value="black" index="1" type="java.lang.String"></constructor-arg>
		<constructor-arg value="300000" index="2" type="java.lang.Double"></constructor-arg>
	</bean

猜你喜欢

转载自blog.csdn.net/qq_44866169/article/details/107848280