BeanFactoryAware,在bean中获取beanfacotry

BeanFactoryAware

对于实现了org.springframework.beans.factory.BeanFactoryAware接口的类,当它被BeanFactory创建后,它会拥有一个指向创建它的BeanFactory的引用。

public interface BeanFactoryAware {

    void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
这样bean可以以编程的方式操控创建它们的BeanFactory,当然我们可以将引用的BeanFactory造型(cast)为已知的子类型来获得更多的功能。它主要用于通过编程来取得BeanFactory所管理的其他bean。虽然在有些场景下这个功能很有用,但是一般来说应该尽量避免使用,因为这样将使代码与Spring耦合在一起,而且也有违反转控制的原则(协作者应该作为属性提供给bean)。

与BeanFactoryAware等效的另一种选择是使用org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean。不过该方法依然没有降低与Spring的耦合,但是它并没有像BeanFactoryAware那样,违反IoC原则。)

ObjectFactoryCreatingFactoryBean是 FactoryBean 的一个实现,它返回一个指向工厂对象的引用,该对象将执行bean的查找。ObjectFactoryCreatingFactoryBean类实现了BeanFactoryAware接口;被实际注入到客户端bean的是ObjectFactory接口的一个实例。这是Spring提供的一个接口(因而依旧没有完全与Spring解耦),客户端可以使用ObjectFactory的getObject()方法来查找bean(在其背后,ObjectFactory实例只是简单的将调用委派给BeanFactory,让其根据bean的名称执行实际的查找)。你要做的全部事情就是给ObjectFactoryCreatingFactoryBean提供待查找bean的名字。让我们看一个例子:

package x.y;

public class NewsFeed {
   
    private String news;

    public void setNews(String news) {
        this.news = news;
    }

    public String getNews() {
        return this.toString() + ": '" + news + "'";
    }
}
package x.y;

import org.springframework.beans.factory.ObjectFactory;

public class NewsFeedManager {

    private ObjectFactory factory;

    public void setFactory(ObjectFactory factory) {
        this.factory = factory;
    }

    public void printNews() {
        // here is where the lookup is performed; note that there is no
        // need to hard code the name of the bean that is being looked up...
        NewsFeed news = (NewsFeed) factory.getObject();
        System.out.println(news.getNews());
    }
}
下述是XML配置:

<beans>
    <bean id="newsFeedManager" class="x.y.NewsFeedManager">
        <property name="factory">
            <bean
class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
                <property name="targetBeanName">
                    <idref local="newsFeed" />
                </property>
            </bean>
        </property>
    </bean>
    <bean id="newsFeed" class="x.y.NewsFeed" scope="prototype">
        <property name="news" value="... that's fit to print!" />
    </bean>
</beans>
这里有一个测试用的小程序:在NewsFeedManager的printNews()方法里,每次针对被注入的ObjectFactory的调用,实际上返回的是一个新的(prototype)newsFeed bean实例。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.NewsFeedManager;

public class Main {

    public static void main(String[] args) throws Exception {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
        NewsFeedManager manager = (NewsFeedManager) ctx.getBean("newsFeedManager");
        manager.printNews();
        manager.printNews();
    }
}
上述程序的执行输出如下所示(当然,返回结果会根据你机器的不同而不同)

x.y.NewsFeed@1292d26: '... that's fit to print!'
x.y.NewsFeed@5329c5: '... that's fit to print!'

你可能感兴趣的:(spring,编程,bean,prototype,IOC)