spring Ioc的理解

1.我对spring的理解

(创建bean的三种方式:1、XML文件方式;2、Configure类方式;3、注解annotation方式。这里讨论XML方式,及其内部原理)

spring的本质就是通过XML配置来执行java代码,如新建对象(bean)、设置对象的依赖关系、调用对象的方法、生命周期的管理等。

a.调用构造器创建对象,用<bean.../>元素;

b.调用setter方法完成依赖注入,用<property.../>元素;

c.调用getter方法获取属性值,用PropertyPathFactoryBean工厂bean;

d.调用普通方法来进行运算,用MethodInvokingFactoryBean工厂bean;

e.直接获取属性值,用FieldRetrievingFactoryBean工厂bean;

2.bean的生成方式

a.调用类的构造器来创建bean:

<bean id="database" class="dao.Database" />

b.通过工厂方法创建bean:

(1)通过静态工厂方法创建bean;

<!-- spring通过静态工厂类的静态方法来创建bean,需指定静态方法 -->
<bean id="staticUser" class="factory.StaticFactory" factory-method="getBeing">
	<!-- 指定静态工厂方法的参数 -->
	<constructor-arg name="arg" value="user" />
</bean>
定义工厂类和静态工厂方法,spring通过调用静态工厂类的静态方法来创建bean。

(2)通过实例工厂方法创建bean:

<!-- 配置实例工厂类的bean对象,spring通过调用bean对象的工厂方法来创建其它bean -->
<bean id="instanceFactoryClass" class="factory.InstanceFactory" />
<bean id="instanceUser" factory-bean="instanceFactoryClass" factory-method="getBeing">
	<!-- 指定实例工厂方法的参数 -->
	<constructor-arg name="arg" value="user" />
</bean>
定义工厂类和实例工厂方法,spring通过调用工厂bean对象的工厂方法来创建新的bean。

c.通过各种FactoryBean(工厂bean)来创建bean:

(1)PropertyPathFactoryBean,用来获取目标bean的属性值(实际是其getter方法的返回值);

<!-- 通过“属性获取工厂Bean”获取目标bean的property,PropertyPathFactoryBean返回值(基本数值类型or对象)在最外层,则把返回值注册为容器中一个bean,bean名字为id -->
<bean id="vipPropertyBean" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
	<property name="targetBeanName" value="vipUser"></property>
	<property name="propertyPath" value="user.username"></property>
</bean>

因为返回值的bean在<beans>目录下,则注册为容器中的bean。

<!-- 简写形式,直接通过指定"已存在的bean的id.property1.property2"(相当于targetBeanName.propertyPath)来获取bean的属性值,因为返回值在最外层,则注册为容器中的bean,bean名字为"已存在的bean的id.property1.property2" -->
<bean id="vipUser.user.username" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
简写形式,注册为容器中的bean。
<!-- 将返回值注册为inner bean,并将其作为依赖值注入到其它bean中。但是容器无法通过id获取到inner bean -->
<bean id="propertyBeanToUserBean" class="bean.User">
	<property name="username">
		<bean id="vipUser.user.username" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
	</property>
	<property name="password">
		<bean id="vipUser.user.password" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
	</property>
</bean>
因为返回的是inner bean,则作为依赖被注入,spring容器无法获取此bean。
(2)FieldRetrievingFactoryBean,用来获取类的静态属性值、或者对象的实例属性值(几乎没用,因为对象的属性值为private,应该通过getter方法获取):

<bean id="java.sql.Connection.TRANSACTION.SERIALIZABLE" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean"/>
简写方法,获取类的静态属性值,因为在<beans.../>目录下,则注册为容器中的bean。
(3)MethodInvokingFactoryBean,用来调用类的静态方法、或者调用bean对象的实例方法。若有返回值则可注册为容器中的bean或者作为依赖注入其它bean中:

<bean id="methodInvokedBean" class="bean.TestMethodInvokingFactoryBean"/>
<bean id="getMethodBean2" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
	<property name ="targetObject" ref="methodInvokedBean"></property>
	<property name="targetMethod" value="func2"></property>
	<property name="arguments">
		<list>
			.....
		</list>
	</property>
</bean>

调用bean的实例方法,可输入方法参数;因为在<beans.../>目录下,则生成容器中的bean,又因为此处没有返回值,则可不用指明bean id。

<bean id="getMethodBean1" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
		<property name = "targetClass" value="bean.TestMethodInvokingFactoryBean"/>
		<property name="targetMethod" value="func1"/>
</bean>
调用类的静态方法,同样可选择是否输入参数or根据位置判断是否注册为容器中的bean。

(4)自定义工厂bean,需要实现FactoryBean接口:

/*
 * factorybean(工厂bean),用来创建其它的bean对象
 */
public class BeingFactoryBean implements FactoryBean<Object>{

	public String targetBean;
		
	public void setTargetBean(String targetBean) {
		this.targetBean = targetBean;
	}

	//工厂bean的此方法用来生产bean
	@Override
	public Object getObject() throws Exception {
		// TODO Auto-generated method stub		
		if(targetBean.equalsIgnoreCase("user"))
			return new User();
		else
			return new Animal();
	}

	@Override
	public Class getObjectType() {
		// TODO Auto-generated method stub
		return Object.class;
	}

	@Override
	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return false;
	}

}
<!-- 配置工厂bean,返回其生产的bean -->
<bean id="factoryBeanProduct" class="bean.BeingFactoryBean">
	<property name="targetBean" value="user" />
</bean>

自定义FactoryBean,通过<property.../>来驱动setter方法来设置参数,此参数会影响getObject()方法生成bean的结果。

3.依赖注入

a.通过构造器完成依赖注入:

<!-- spring容器通过构造器构造bean,并完成属性值注入 -->
<bean id="constructorBean" class="bean.ConstructorBean">
	<constructor-arg name="user" ref="zp" index="0" />
	<constructor-arg name="isMan" value="yes" index="1" />
</bean>
通过构造器完成依赖注入,即在新建对象时就注入参数值。

b.通过setter方法完成依赖注入:

<bean id="dbservice" class="service.DbService" scope="singleton">
	<!-- 通过setter方法完成属性的依赖注入 -->
	<property name="database" ref="database" />
	<!-- 通过setter方法完成属性的值注入 -->
	<property name="name" value="基本类型的属性值"/>
</bean>
通过<property.../>触发setter方法来完成依赖注入。

c.注入的类型:

通过这些元素: value、ref、bean、list、set、map,在它们的‘=’后面or元素里面为构造器或者setter方法指定参数值。
(1)注入普通的属性值(基本数值类型、string等)
<property name="name" value="zp"/>
<property name="name" >
      <value>
         zp
      </value>
</property>
(2)注入其它的bean对象
<property name="user" ref="zpp"/>
<property name="user">
      <ref bean = "zpp">
</property>








(3)注入集合类型的值

<!-- Bean的属性是集合 -->
<bean id="collectionBean" class="bean.CollectionBean">
	<property name="list">
		<list>
			<value>list1</value>
			<value>list2</value>
			<value>list3</value>
		</list>
	</property>
	<property name="map">
		<map>
			<entry key="key1" value="value1"></entry>
			<entry key="key2" value="value2"></entry>
			<entry key="key3" value="value3"></entry>
		</map>
	</property>
	<property name="array">
		<list>
			<value>array1</value>
			<value>array2</value>
			<value>array3</value>
		</list>
	</property>
</bean>

d.高级依赖关系:

通过PropertyPathFactoryBean获取getter方法的返回值、FiledRetrievingFactoryBean获取的属性值、MethodInvokingFactoryBean获取的方法返回值、自定义的FactoryBean获取的值都可以作为依赖注入其它bean中。(当然也可以注册为容器中的bean)

5.生命周期和作用域

作用域:

singleton:单例模式;prototype:全局模式;request:请求模式;session:回话模式。

生命周期:

<bean id="user" class="bean.User" init-method="init" destroy-method="close" scope="singleton" />
init-methon:创建Bean实例,其全部属性设置完成后执行的方法;
destory-method:bean实例在容器中被销毁前执行的方法

6.事件机制

(1)容器事件监听器:实现ApplicationListener接口的类

<!-- 配置容器事件监听器 -->
<bean class="listener.Listener" scope="prototype" />
创建、加载spring容器时,会自动触发容器事件(有很多不同的容器事件),容器监听器会捕捉到此事件,并执行onApplicationEvent()方法

(2)具有意识的bean

<!-- spring容器创建该bean后自动调用其方法,把容器对象自身作为参数 -->
<bean id="awareBean" class="bean.ApplicationContextAwareBean" />
实现ApplicationContextAware接口的类,在创建此bean后,容器会调用其一个方法,将applicationContext作为参数传到此bean对象的一个属性中。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值