spring核心:bean工厂的装配 5

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

本文中主要包含:

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>

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值