KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > aop > framework > autoproxy > target > AbstractBeanFactoryBasedTargetSourceCreator


1 /*
2  * Copyright 2002-2007 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.aop.framework.autoproxy.target;
18
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21
22 import org.springframework.aop.TargetSource;
23 import org.springframework.aop.framework.autoproxy.TargetSourceCreator;
24 import org.springframework.aop.target.AbstractBeanFactoryBasedTargetSource;
25 import org.springframework.beans.factory.BeanFactory;
26 import org.springframework.beans.factory.BeanFactoryAware;
27 import org.springframework.beans.factory.DisposableBean;
28 import org.springframework.beans.factory.support.AbstractBeanFactory;
29 import org.springframework.beans.factory.support.DefaultListableBeanFactory;
30 import org.springframework.beans.factory.support.RootBeanDefinition;
31
32 /**
33  * Convenient superclass for
34  * {@link org.springframework.aop.framework.autoproxy.TargetSourceCreator}
35  * implementations that require creating multiple instances of a prototype bean.
36  *
37  * <p>Uses an internal BeanFactory to manage the target instances,
38  * copying the original bean definition to this internal factory.
39  * This is necessary because the original BeanFactory will just
40  * contain the proxy instance created through auto-proxying.
41  *
42  * <p>Requires running in an
43  * {@link org.springframework.beans.factory.support.AbstractBeanFactory}.
44  *
45  * @author Rod Johnson
46  * @author Juergen Hoeller
47  * @see org.springframework.aop.target.AbstractBeanFactoryBasedTargetSource
48  * @see org.springframework.beans.factory.support.AbstractBeanFactory
49  */

50 public abstract class AbstractBeanFactoryBasedTargetSourceCreator
51         implements TargetSourceCreator, BeanFactoryAware, DisposableBean {
52
53     protected final Log logger = LogFactory.getLog(getClass());
54
55     private AbstractBeanFactory beanFactory;
56
57     private DefaultListableBeanFactory internalBeanFactory;
58
59
60     public final void setBeanFactory(BeanFactory beanFactory) {
61         if (!(beanFactory instanceof AbstractBeanFactory)) {
62             throw new IllegalArgumentException JavaDoc(
63                     "Cannot do auto-TargetSource creation with a BeanFactory that doesn't extend AbstractBeanFactory: " +
64                     beanFactory);
65         }
66         this.beanFactory = (AbstractBeanFactory) beanFactory;
67         this.internalBeanFactory = new DefaultListableBeanFactory(beanFactory);
68     }
69
70     /**
71      * Return the BeanFactory that this TargetSourceCreators runs in.
72      */

73     protected final BeanFactory getBeanFactory() {
74         return this.beanFactory;
75     }
76
77     /**
78      * Destroys the internal BeanFactory on shutdown of the TargetSourceCreator.
79      */

80     public void destroy() {
81         this.internalBeanFactory.destroySingletons();
82     }
83
84
85     public final TargetSource getTargetSource(Class JavaDoc beanClass, String JavaDoc beanName) {
86         AbstractBeanFactoryBasedTargetSource targetSource =
87                 createBeanFactoryBasedTargetSource(beanClass, beanName);
88         if (targetSource == null) {
89             return null;
90         }
91
92         if (logger.isDebugEnabled()) {
93             logger.debug("Configuring AbstractBeanFactoryBasedTargetSource: " + targetSource);
94         }
95
96         // We need to override just this bean definition, as it may reference other beans
97
// and we're happy to take the parent's definition for those.
98
// Always use a prototype.
99
RootBeanDefinition bd = this.beanFactory.getMergedBeanDefinition(beanName);
100         RootBeanDefinition bdCopy = new RootBeanDefinition(bd);
101         bdCopy.setSingleton(!isPrototypeBased());
102         this.internalBeanFactory.registerBeanDefinition(beanName, bdCopy);
103
104         // Complete configuring the PrototypeTargetSource.
105
targetSource.setTargetBeanName(beanName);
106         targetSource.setBeanFactory(this.internalBeanFactory);
107
108         return targetSource;
109     }
110
111     /**
112      * Return whether this TargetSourceCreator is prototype-based.
113      * The "singleton" flag of the target bean definition will be set accordingly.
114      * <p>Default is "true".
115      * @see org.springframework.beans.factory.config.BeanDefinition#isSingleton()
116      */

117     protected boolean isPrototypeBased() {
118         return true;
119     }
120
121     /**
122      * Subclasses must implement this method to return a new AbstractPrototypeBasedTargetSource
123      * if they wish to create a custom TargetSource for this bean, or <code>null</code> if they are
124      * not interested it in, in which case no special target source will be created.
125      * Subclasses should not call <code>setTargetBeanName</code> or <code>setBeanFactory</code>
126      * on the AbstractPrototypeBasedTargetSource: This class' implementation of
127      * <code>getTargetSource()</code> will do that.
128      * @param beanClass the class of the bean to create a TargetSource for
129      * @param beanName the name of the bean
130      * @return the AbstractPrototypeBasedTargetSource, or <code>null</code> if we don't match this
131      */

132     protected abstract AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(
133             Class JavaDoc beanClass, String JavaDoc beanName);
134
135 }
136
Popular Tags