KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > factory > config > ObjectFactoryCreatingFactoryBean


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.factory.config;
18
19 import org.springframework.beans.BeansException;
20 import org.springframework.beans.factory.BeanFactory;
21 import org.springframework.beans.factory.BeanFactoryAware;
22 import org.springframework.beans.factory.ObjectFactory;
23 import org.springframework.util.Assert;
24
25 /**
26  * A {@link org.springframework.beans.factory.FactoryBean} implementation that
27  * returns a value which is an {@link org.springframework.beans.factory.ObjectFactory}
28  * that in turn returns a bean sourced from a {@link org.springframework.beans.factory.BeanFactory}.
29  *
30  * <p>As such, this may be used to avoid having a client object directly calling
31  * {@link org.springframework.beans.factory.BeanFactory#getBean(String)} to get
32  * a (typically prototype) bean from a
33  * {@link org.springframework.beans.factory.BeanFactory}, which would be a
34  * violation of the inversion of control principle. Instead, with the use
35  * of this class, the client object can be fed an
36  * {@link org.springframework.beans.factory.ObjectFactory} instance as a
37  * property which directly returns only the one target bean (again, which is
38  * typically a prototype bean).
39  *
40  * <p>A sample config in an XML-based
41  * {@link org.springframework.beans.factory.BeanFactory} might look as follows:
42  *
43  * <pre class="code">&lt;beans>
44  *
45  * &lt;!-- Prototype bean since we have state -->
46  * &lt;bean id="myService" class="a.b.c.MyService" singleton="false"/>
47  *
48  * &lt;bean id="myServiceFactory"
49  * class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
50  * &lt;property name="targetBeanName">&lt;idref local="myService"/>&lt;/property>
51  * &lt;/bean>
52  *
53  * &lt;bean id="clientBean" class="a.b.c.MyClientBean">
54  * &lt;property name="myServiceFactory" ref="myServiceFactory"/>
55  * &lt;/bean>
56  *
57  *&lt;/beans></pre>
58  *
59  * <p>The attendant <code>MyClientBean</code> class implementation might look
60  * something like this:
61  *
62  * <pre class="code">package a.b.c;
63  *
64  *import org.springframework.beans.factory.ObjectFactory;
65  *
66  *public class MyClientBean {
67  *
68  * private ObjectFactory myServiceFactory;
69  *
70  * public void setMyServiceFactory(ObjectFactory myServiceFactory) {
71  * this.myServiceFactory = myServiceFactory;
72  * }
73  *
74  * public void someBusinessMethod() {
75  * // get a 'fresh', brand new MyService instance
76  * MyService service = this.myServiceFactory.getObject();
77  * // use the service object to effect the business logic...
78  * }
79  *}</pre>
80  *
81  * <p>An alternate approach to this application of an object creational pattern
82  * would be to use the {@link ServiceLocatorFactoryBean}
83  * to source (prototype) beans. The {@link ServiceLocatorFactoryBean} approach
84  * has the advantage of the fact that one doesn't have to depend on any
85  * Spring-specific interface such as {@link org.springframework.beans.factory.ObjectFactory},
86  * but has the disadvantage of requiring runtime class generation. Please do
87  * consult the
88  * {@link ServiceLocatorFactoryBean ServiceLocatorFactoryBean JavaDoc} for a
89  * fuller discussion of this issue.
90  *
91  * @author Colin Sampaleanu
92  * @since 2004-05-11
93  * @see org.springframework.beans.factory.ObjectFactory
94  * @see ServiceLocatorFactoryBean
95  */

96 public class ObjectFactoryCreatingFactoryBean extends AbstractFactoryBean
97         implements BeanFactoryAware {
98
99     private String JavaDoc targetBeanName;
100
101     private BeanFactory beanFactory;
102
103
104     /**
105      * Set the name of the target bean.
106      * <p>
107      * The target does not <i>have</> to be a prototype bean, but realisticially
108      * always will be (because if the target bean were a singleton, then said
109      * singleton bean could simply be injected straight into the dependent object,
110      * thus obviating the need for the extra level of indirection afforded by
111      * the approach encapsulated by this class). Please note that no exception
112      * will be thrown if the supplied <code>targetBeanName</code> does not
113      * reference a prototype bean.
114      */

115     public void setTargetBeanName(String JavaDoc targetBeanName) {
116         this.targetBeanName = targetBeanName;
117     }
118
119     public void setBeanFactory(BeanFactory beanFactory) {
120         this.beanFactory = beanFactory;
121     }
122
123     protected Object JavaDoc createInstance() {
124         return new ObjectFactory() {
125             public Object JavaDoc getObject() throws BeansException {
126                 return beanFactory.getBean(targetBeanName);
127             }
128         };
129     }
130
131     public void afterPropertiesSet() throws Exception JavaDoc {
132         Assert.hasText(targetBeanName, "targetBeanName is required");
133         super.afterPropertiesSet();
134     }
135
136     public Class JavaDoc getObjectType() {
137         return ObjectFactory.class;
138     }
139
140 }
141
Popular Tags