您的位置:首页 > 编程语言 > Java开发

spring核心:bean工厂的装配 5

2010-10-21 21:11 330 查看
本文中主要包含:

19.方法的注入

20.bean的生命周期接口

21.让bean知道自己的身份

22.父bean和子bean

19.方法的注入

方法的注入的引入主要是用来解决下面的问题:在spring中,一个singleton bean A,在每次方法调用中需要产生一个non-singleton的bean B,spring仅仅会一次创建A,并且设置这个bean的属性,所以无法为外界提供一个不同的B。为此spring中引入了‘方法注入’的概念。

MyLookupBean.java

package beanfactory.coredi;
/**
* @author jefferyxu
*
*/
public class MyLookupBean {

/**
* 这个方法将被spring重写
* @return
*/
protected AnotherBean newAnotherBean() {
return null;
}

public void doSomethingWithAnotherBean() {
AnotherBean anotherBean = new AnotherBean();

System.out.println(anotherBean.hashCode());
}
}


applicationContext.xml:

<!--
lookup方法能够重写bean的抽象方法或者是具体方法,返回的是
容器中的bean实例,这里解决的是singleton类的non-sinlgeton
属性
-->
<bean id="myBean" class="beanfactory.coredi.MyLookupBean"
abstract="false" lazy-init="default" autowire="default">
<lookup-method name="newAnotherBean" bean="anotherBean" />
</bean>


客户端程序:

MyLookupBean myBean1 = (MyLookupBean)context.getBean("myBean");
myBean1.doSomethingWithAnotherBean();

MyLookupBean myBean2 = (MyLookupBean)context.getBean("myBean");
myBean2.doSomethingWithAnotherBean();


20.bean的生命周期接口

spring中提供了一些bean声明周期的接口,其中包含了InitializingBean和DisposableBean。它们可以改变bean的行为。

1.InitializingBean源码如下:

public interface InitializingBean {

/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
void afterPropertiesSet() throws Exception;
}


这个接口的使用方式如下:

AnotherBean.java:

package beanfactory.coredi;
public class AnotherBean {

/**
* bean的生命周期,一种简单的方法是实现spring的
* 接口,但是 一般不提倡这么做,因为这样的代码会和
* spring紧耦合
*/
public void initBean(){
System.out.println("init bean...");
}

public void destroyBean(){
System.out.println("destroy bean...");
}
}


applicationContext.xml:

<bean id="anotherBean" class="beanfactory.coredi.AnotherBean"
abstract="false" lazy-init="default" autowire="default" init-method="initBean"
destroy-method="destroyBean">
</bean>




2.DisposableBean

DisposableBean源码如下:

public interface DisposableBean {
/**
* Invoked by a BeanFactory on destruction of a singleton.
* @throws Exception in case of shutdown errors.
* Exceptions will get logged but not rethrown to allow
* other beans to release their resources too.
*/
void destroy() throws Exception;
}


使用方法和上面相似。

21.让bean知道自己的身份

1.BeanNameAware,spring通过该接口调用bean,此时该bean得到自身的一些信息,代码如下:

public interface BeanNameAware {
/**
* Set the name of the bean in the bean factory that created this bean.
* <p>Invoked after population of normal bean properties but before an
* init callback such as {@link InitializingBean#afterPropertiesSet()}
* or a custom init-method.
* @param name the name of the bean in the factory.
* Note that this name is the actual bean name used in the factory, which may
* differ from the originally specified name: in particular for inner bean
* names, the actual bean name might have been made unique through appending
* "#..." suffixes. Use the {@link BeanFactoryUtils#originalBeanName(String)}
* method to extract the original bean name (without suffix), if desired.
*/
void setBeanName(String name);
}


使用方法:

AwareBean.java:

/**
*
*/
package beanfactory.nature;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
/**
* @author jefferyxu
*
*/
public class AwareBean implements BeanNameAware, BeanFactoryAware {
private String beanName;
private BeanFactory beanFactory;

/* (non-Javadoc)
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
*/
@Override
public void setBeanName(String name) {
// TODO Auto-generated method stub
this.beanName = name;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
// TODO Auto-generated method stub
this.beanFactory = beanFactory;
}
public void init() {
System.out.println("bean factory: " +this.beanFactory +
" bean name : " + this.beanName);
}
}


applicationContext.xml:

<bean id="awareBean" class="beanfactory.nature.AwareBean"
abstract="false" lazy-init="default" autowire="default" init-method="init">
</bean>


2.BeanFactoryAware:

如果bean实现了上面的接口的话,那么当sping创建这个bean的时候,向这个bean中注入了产生这个bean的factory的引用。BeanFactoryAware代码:

public interface BeanFactoryAware {
/**
* Callback that supplies the owning factory to a bean instance.
* <p>Invoked after the population of normal bean properties
* but before an initialization callback such as
* {@link InitializingBean#afterPropertiesSet()} or a custom init-method.
* @param beanFactory owning BeanFactory (never <code>null</code>).
* The bean can immediately call methods on the factory.
* @throws BeansException in case of initialization errors
* @see BeanInitializationException
*/
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}


使用方法和上面的类似。

3.FactoryBean

FactoryBean它本身就是一个工厂,同时也是一个bean组件。有时候需要向spring中请求factory本身,而不是factory产生的类本身,那么这是在使用getBean时,需要在bean name前加上&符号,例如getBean("&BeanName").

22.父bean和子bean

一个bean的定义中可能包含了许多的定义,而一个bean的配置能够继承其父bean的属性,只需要设置与父bean不相同的属性。实例:

<!--
abstract="true"表明不能使用getBean得到对象的实例
-->
<bean id="parentBean" class="beanfactory.childbean.ParentBean"
abstract="true" p:name="parent">
<property name="age">
<value type="int">99</value>
</property>
</bean>

<!-- 这里只是重写了name属性,那么age属性就继承自parentBean -->
<bean id="childBean" class="beanfactory.childbean.ChildBean">
<property name="name" value="override"></property>
<property name="age" value="100"></property>
</bean>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: