Search

7.7. Bean Factory

download PDF
When you want more than one instance of a particular bean, you need to use the bean factory pattern. The job of the Microcontainer is to configure and install the bean factory as if it were a plain bean. Then you need to invoke the bean factory's createBean method.
By default, the Microcontainer creates a GenericBeanFactory instance, but you can configure your own factory. The only limitation is that its signature and configuration hooks are similar to the one of AbstractBeanFactory.

Example 7.15. Generic Bean Factory

<bean name="Object" class="java.lang.Object"/>
<beanfactory name="DefaultPrototype" class="org.jboss.demos.ioc.factory.Prototype">
  <property name="value"><inject bean="Object"/></property>
</beanfactory>
<beanfactory name="EnhancedPrototype" class="org.jboss.demos.ioc.factory.Prototype" factoryClass="org.jboss.demos.ioc.factory.EnhancedBeanFactory">
  <property name="value"><inject bean="Object"/></property>
</beanfactory>
<beanfactory name="ProxiedPrototype" class="org.jboss.demos.ioc.factory.UnmodifiablePrototype" factoryClass="org.jboss.demos.ioc.factory.EnhancedBeanFactory">
  <property name="value"><inject bean="Object"/></property>
</beanfactory>
<bean name="PrototypeCreator" class="org.jboss.demos.ioc.factory.PrototypeCreator">
  <property name="default"><inject bean="DefaultPrototype"/></property>
  <property name="enhanced"><inject bean="EnhancedPrototype"/></property>
  <property name="proxied"><inject bean="ProxiedPrototype"/></property>
</bean>
			
			
			
			

See Example 7.16, “Extended BeanFactory” for usage of an extended BeanFactory.

Example 7.16. Extended BeanFactory

public class EnhancedBeanFactory extends GenericBeanFactory {
    public EnhancedBeanFactory(KernelConfigurator configurator)
    {
	super(configurator);
    }
    public Object createBean() throws Throwable
    {
	Object bean = super.createBean();
	Class clazz = bean.getClass();
	if (clazz.isAnnotationPresent(SetterProxy.class))
	    {
		Set<Class> interfaces = new HashSet<Class>();
		addInterfaces(clazz, interfaces);
		return Proxy.newProxyInstance(
					      clazz.getClassLoader(),
					      interfaces.toArray(new Class[interfaces.size()]),
					      new SetterInterceptor(bean)
					      );
	    }
	else
	    {
		return bean;
	    }
    }
    protected static void addInterfaces(Class clazz, Set<Class> interfaces)
    {
	if (clazz == null)
	    return;
	interfaces.addAll(Arrays.asList(clazz.getInterfaces()));
	addInterfaces(clazz.getSuperclass(), interfaces);
    }
    private class SetterInterceptor implements InvocationHandler
    {
	private Object target;
	private SetterInterceptor(Object target)
	{
	    this.target = target;
	}
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
	{
	    String methodName = method.getName();
	    if (methodName.startsWith("set"))
		throw new IllegalArgumentException("Cannot invoke setters.");
	    return method.invoke(target, args);
	}
    }
}
public class PrototypeCreator {
    ...
	public void create() throws Throwable
    {
	ValueInvoker vi1 = (ValueInvoker)bfDefault.createBean();
	vi1.setValue("default");
	ValueInvoker vi2 = (ValueInvoker)enhanced.createBean();
	vi2.setValue("enhanced");
	ValueInvoker vi3 = (ValueInvoker)proxied.createBean();
	try
	    {
		vi3.setValue("default");
		throw new Error("Should not be here.");
	    }
	catch (Exception ignored)
	    {
	    }
    }
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.