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!'
对于实现了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!'