Spring笔记二

2 篇文章 0 订阅

通过构造器来创建bean对象

有name的创建

	<bean id="person1" class="com.yxm.entity.Person">
		<!-- 构造器有多少个需要传入的值就传多少个 -->
		<!-- public Person(String name, String gender,Integer age) -->
		<constructor-arg name="name" value="test01"></constructor-arg>
		<constructor-arg name="age" value="18"></constructor-arg>
		<constructor-arg name="gender" value="男"></constructor-arg>
	</bean>

没有name的创建

可以没有name,但是前提是必须和你要的构造器的参数一一对应,或者说你可以使用constructor-arg标签的index属性

<bean id="person2" class="com.yxm.entity.Person">
		<!-- 构造器有多少个需要传入的值就传多少个 -->
		<!-- public Person(String name, String gender,Integer age) -->
		<constructor-arg value="test01"></constructor-arg>
		<constructor-arg value="男" index="1"></constructor-arg>
		<constructor-arg value="18"></constructor-arg>
	</bean>

这个时候要是出现两个重载的构造器,然后你又不想用name的话,那就用上constructor-arg标签的type属性来区分吧

<bean id="person3" class="com.yxm.entity.Person">
		<!-- 构造器有多少个需要传入的值就传多少个 -->
		<!-- public Person(String name, String gender) -->
		<!-- public Person(String name, Integer age) -->
		<constructor-arg value="test01"></constructor-arg>
		<constructor-arg value="男" type="java.lang.String"></constructor-arg>
</bean>

最好还是用name吧,看着都舒服

通过p名称空间为bean属性赋值

给我的感觉是,没啥感觉,就是简化了代码,如果属性多了用这个赋值感觉很不美观,但是可以作为了解
首先来引入p名称空间
如果你是用sts插件来创建的spring的配置文件的话
在这里插入图片描述
点击,以后会出现如下界面
在这里插入图片描述
点击,然后会发现多了红线这行代码(util那行代码是后面用到的)
在这里插入图片描述
如果不是的话,那么就直接把红线那部分代码复制到图中位置
xmlns:p=“http://www.springframework.org/schema/p”
然后就是使用了

<!--这里就是为age属性赋值了-->
<bean id="person4" class="com.yxm.entity.Person" p:age="12"></bean>

正确为各种属性赋值

使用null值

		<property name="name">
			<!-- 复杂类型的赋值 -->
			<null/>
		</property>

引用类型赋值(引用其他bean,使用内部bean)

引用其他bean

<!-- 被引用的bean对象 -->
	<bean id="car1" class="com.yxm.entity.Car">
		<property name="carName" value="路虎"></property>
		<property name="color" value="黑色"></property>
		<property name="price" value="3000000"></property>
	</bean>
<!-- 属性ref的意思是引用,所以它和容器里面取出来的car对象是一致的-->
<!--所以你变它变--!>
<property name="car" ref="car1"></property>
<!--或者<property name="car"><ref bean="car1"/> </property>--!>

使用内部bean(仅供内部使用,就算你对这个bean赋予id属性还是没什么用)

<!-- 引用内部的bean对象,就是相当于创建一个new car对象然后赋值给属性 -->
		<property name="car">
			<bean class="com.yxm.entity.Car">
				<property name="carName" value="路虎"></property>
				<property name="color" value="蓝色"></property>
				<property name="price" value="3000000"></property>
			</bean>
		</property>

集合类型赋值(list,map,properties)

<!-- 测试集合类型的变量赋值 -->
<bean id="book1" class="com.yxm.entity.Book" p:bookName="东游记"></bean>
<!-- 为list类型的变量赋值 -->
		<property name="books">
			<!-- 就相当于是list=new ArrayList<>() -->
			<list>
				<bean id="book1" class="com.yxm.entity.Book" p:bookName="西游记"></bean>
				<ref bean="book1"/>
			</list>
		</property>
<!-- 为map类型的变量赋值 -->
		<property name="map">
			<!-- 相当于是为这个变量赋值map = new LinkedHashMap<>() -->
			<map>
				<!-- 表示一个键值对   注意我这边使用的是Map<String,Object> -->
				<entry key="key01" value="普通"></entry>
				<entry key="key01" value="123"></entry>
				<entry key="key02" value-ref="book1"></entry>
				<entry key="key03">
					<bean class="com.yxm.entity.Car" p:carName="路虎"></bean>
				</entry>
				<!-- <entry key-ref="" value-type=""></entry> -->
				<!-- 当然entry里面还是可以嵌套其他的复杂类型变量的 -->
			</map>
		</property>
<!-- 为Properties类型的变量赋值 -->
		<property name="properties">
			<!-- 相当于赋值new Properties()-->
			<props>
				<!-- 因为properties 的键值对都是String类型的,所以prop标签没有value属性 -->
				<prop key="username">root</prop>
			</props>
		</property>

util名称空间创建集合类型的bean

和p名称空间导入方式相同,选中util即可,若不是sts插件则
xmlns:util=“http://www.springframework.org/schema/util”

<!-- util名称空间创建集合类型的bean -->
	<!-- 就是能够创建类似于bean的对象,当然这些对象是list map set等等 -->
	<!-- 这个也可以在内部使用,也就是意味着内部的也能够在其他的bean中调用 -->
	<util:map id="map1" map-class="java.util.HashMap">
		<!-- 直接添加元素即可 -->
		<entry key="key01" value="普通"></entry>
		<entry key="key01" value="123"></entry>
		<entry key="key02" value-ref="book1"></entry>
		<entry key="key03">
			<bean class="com.yxm.entity.Car" p:carName="路虎"></bean>
		</entry>
	</util:map>
<!-- 测试util名称空间 -->
<property name="map" ref="map1">
		</property>

级联属性(属性的属性)赋值

关键在于property这个标签的name属性上面

<!-- 级联属性(属性的属性)赋值 -->
	<bean id="person8" class="com.yxm.entity.Person">
		<property name="car" ref="car1"></property>
		<!-- 现在是修改赋值进行的值,比如修改车的价格 -->
		<!-- 需要注意的是这边修改的话因为car是ref的缘故就会导致ref引用的那个对象也会发生改变 -->
		<property name="car.price" value="90000000"></property>
	</bean>

通过继承实现bean配置信息的重用和生成一个只能是配置文件内部调用的bean对象,不能够被getBean获取

bean标签的属性parent,就是指定当前bean的配置信息继承于那个 和 bean标签的属性abstract="true

<!-- 通过bean标签的parent进行实现,构造器也是可以的,而且下方这种person10有person9和person1的配置属性 -->
	<!-- 可以有一个专门只供xml内部使用的bean对象,也就是在外面的getBean是获得不到的,bean标签的abstract属性-->
	<bean id="person9" class="com.yxm.entity.Person" parent="person1" abstract="true">
		<property name="age" value="13"></property>
	</bean>
	<bean id="person10" class="com.yxm.entity.Person" parent="person9">
		<property name="gender" value="男"></property>
	</bean>

bean之间的依赖(单纯的改变bean的创建的先后顺序)

这个作为了解就好一般用不到,貌似--------bean标签的depends-on="",里面写其他的beanid,多个的话用逗号隔开

<!-- bean标签的depend-on属性能够决定在实现当前的bean对象的之前会先创建哪一个或者几个bean对象 -->
<!--这个就表示当前的bean对象是在person9  person10 后生成--!>
	<!-- <bean depends-on="person9,person10"></bean> -->

bean的作用域

取决于bean标签的scope属性

<!-- 
		prototype:多实例,只有在你需要 它的时候容器才会进行创建并且每次创建出来的bean实例都是不同的
		singleton:单实例,是bean标签的默认值,是在容器创建的时候已经生成的,并且获取的时候都是已经创建好的那个
		request:在web环境下,同一次请求创建一个bean对象(一般不使用)
		session:在web环境下,同一次会话创建一个bean对象(一般不使用)
	 -->
	<bean id="car3" class="com.yxm.entity.Car"></bean>
	<bean id="car2" class="com.yxm.entity.Car" scope="prototype"></bean>
//测试多实例
		Car car01 = ac.getBean("car2",Car.class);
		Car car02 = ac.getBean("car2",Car.class);
		System.out.println(car01 == car02);
结果:false(单实例测试类似,返回true)

静态,实例工厂方法创建bean

bean的默认创建就是框架利用反射new出来的bean实例
工厂模式:工厂帮我们创建对象,也就是有一个专门帮我们创建对象的类这个类就是工厂
静态工厂:工厂本身不用创建对象,通过静态方法调用,对象 = 工厂类.工厂方法名();
实例工厂:工厂本身需要创建对象,工厂类 工厂对象 = new工厂类();工厂对象.获取对象的方法名();

静态工厂的创建

首先创建一个静态工厂类,里面有获取Car类的方法,然后再spring的配置文件中进行相关配置

//Car类的静态工厂
public class CarStaticFactory {

	public static Car getInstance(String carName) {
		Car car = new Car();
		car.setCarName(carName);
		car.setColor("蓝色");
		car.setPrice(5000000);
		return car;
	}
}
//spring配置文件
<!-- 静态工厂创建需要的bean对象 factory-method就是获取对象的方法-->
	<bean id="car4" class="com.yxm.factory.CarStaticFactory" factory-method="getInstance">
		<!-- 需要下面的标签来传递参数 -->
		<!-- 因为只有一个参数,所以就不写name了 -->
		<constructor-arg value="路虎"></constructor-arg>
	</bean>
然后调用getBean方法就行了

实例工厂的创建

先创建一个实例工厂的类对象,然后在spring配置文件中进行相应的配置

//Car类的实例工厂
public class CarInstanceFactory {

	public Car getInstance(String carName) {
		Car car = new Car();
		car.setCarName(carName);
		car.setColor("蓝色");
		car.setPrice(5000000);
		return car;
	}
}
//Spring配置文件
<!-- 实例工厂创建需要的bean对象
			先创建实例工厂所对应的bean对象,然后就是类似于静态工厂获取的形式,只是多了一个属性factory-bean
	 -->
	 <bean id="carFactory" class="com.yxm.factory.CarInstanceFactory"></bean>
	 <bean id="car5" class="com.yxm.entity.Car" factory-bean="carFactory" factory-method="getInstance">
	 	<!-- 传入参数 -->
	 	<constructor-arg value="宝马"></constructor-arg>
	 </bean>
调用getBean方法即可

FactoryBean来进行创建对象实例

可以理解为spring自带的工厂接口
先创建一个工厂类实现这个接口,并且实现里面的三个抽象方法,然后还是在spring的配置文件中配置就好

public class MyFactoryBeanImpl implements FactoryBean<Car>{
	//如果配置文件中创建的是这个bean实例会自动调用这个方法来获取你所需要的对象实例
	@Override
	public Car getObject() throws Exception {
		// TODO 自动生成的方法存根
		System.out.println("MyFactoryBeanImpl.getObject()");
		Car car = new Car();
		car.setCarName("路虎");
		car.setColor("红色");
		car.setPrice(5000000);
		return car;
	}

	//返回创建的实例对象的类型,Spring会自动进行调用来确定调用的是什么类型
	@Override
	public Class<?> getObjectType() {
		// TODO 自动生成的方法存根
		System.out.println("MyFactoryBeanImpl.getObjectType()");
		return Car.class;
	}

	//是单例?
	@Override
	public boolean isSingleton() {
		// TODO 自动生成的方法存根
		System.out.println("MyFactoryBeanImpl.isSingleton()");
		return false;
	}

}
//spring配置文件
<!-- factoryBean来进行创建对象实例 -->
	 <!-- factoryBean所创建的对象实例都是在你调用getBean的方法的时候才会去创建的,无论是单实例还是多实例
	 		也与接口所对应的方法中的是否为单实例的方法无关,这个方法只是能让你获取到的对象是单还是多
	  -->
	 <bean id="myFactoryBean" class="com.yxm.factory.MyFactoryBeanImpl"></bean>
然后调用getBean即可
这个方法一般都是在进行复杂类型的bean对象实例的时候会用到,比如那些和spring整合的时候,如SQLSessionFactory(知乎上看到的)
然后我有对这三个方法测试了一下
		Car car3 = ac.getBean("myFactoryBean",Car.class);
		Car car4 = ac.getBean("myFactoryBean",Car.class);
		System.out.println(car3 == car4);
结果
MyFactoryBeanImpl.isSingleton()
MyFactoryBeanImpl.isSingleton()
MyFactoryBeanImpl.getObject()
car创建
MyFactoryBeanImpl.isSingleton()
MyFactoryBeanImpl.getObject()
car创建
false
isSingleton这个方法测试过,你只要加载了那个配置文件就会调用。
而getObject是在你调用getBean的时候调用。

FactoryBean的方法getObjectType()不知道是什么时候调用的,很迷,就算我写它返回不是getObject方法返回的值的类型还是未报错。
若有知晓,烦请告知,不胜感激。
这是看完雷丰阳雷老师的ssm课程的笔记,感谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值