本文中主要包含:
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>
本文介绍了Spring框架中的方法注入概念及其应用场景,并详细探讨了Bean的生命周期接口InitializingBean和DisposableBean的作用及使用方法。此外,还讲解了如何让Bean知道自己的身份以及父Bean和子Bean的配置方式。

被折叠的 条评论
为什么被折叠?



