|
From: Rajeev K. <Ra...@cu...> - 2003-12-04 19:01:50
|
Rod,
I have attached the test files and included the patch below:
Index: BeanNameAutoProxyCreator.java
===================================================================
RCS file:
/cvsroot/springframework/spring/src/org/springframework/aop/framework/suppor
t/BeanNameAutoProxyCreator.java,v
retrieving revision 1.7
diff -u -r1.7 BeanNameAutoProxyCreator.java
--- BeanNameAutoProxyCreator.java 15 Nov 2003 15:30:14 -0000 1.7
+++ BeanNameAutoProxyCreator.java 4 Dec 2003 19:00:43 -0000
@@ -1,59 +1,199 @@
package org.springframework.aop.framework.support;
-
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
-
+import org.apache.commons.lang.StringUtils;
+import org.springframework.aop.TargetSource;
+import org.springframework.aop.target.PrototypeTargetSource;
+import org.springframework.aop.target.SingletonTargetSource;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.PropertyValue;
+import org.springframework.beans.PropertyValues;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.BeanInitializationException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.support.AbstractBeanFactory;
+import
org.springframework.beans.factory.support.DefaultListableBeanFactory;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.support.RuntimeBeanReference;
/**
* Auto proxy creator that identifies beans to proxy via a list of names.
* Checks for direct, "xxx*", and "*xxx" matches.
* @author Juergen Hoeller
+ * @author Rajeev Kaul
* @since 10.10.2003
* @see #setBeanNames
* @see #isMatch
*/
-public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
-
- private List beanNames;
-
- /**
- * Set the names of the beans that should automatically get wrapped with
proxies.
- * A name can specify a prefix to match by ending with "*", e.g.
"myBean,tx*"
- * will match the bean named "myBean" and all beans whose name start with
"tx".
- */
- public void setBeanNames(String[] beanNames) {
- this.beanNames = Arrays.asList(beanNames);
- }
-
- /**
- * Identify as bean to proxy if the bean name is in the configured list of
names.
- */
- protected Object[] getInterceptorsAndAdvisorsForBean(Object bean, String
beanName) {
- if (this.beanNames != null) {
- if (this.beanNames.contains(beanName)) {
- return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
+public class BeanNameAutoProxyCreator
+ extends AbstractAutoProxyCreator
+ implements BeanFactoryAware, InitializingBean
+{
+ private List beanNames;
+ private BeanFactory beanFactory;
+ private String targetClass;
+ private TargetSource target;
+ /**
+ * Set the names of the beans that should automatically get wrapped
with proxies.
+ * A name can specify a prefix to match by ending with "*", e.g.
"myBean,tx*"
+ * will match the bean named "myBean" and all beans whose name start
with "tx".
+ */
+ public void setBeanNames(String[] beanNames)
+ {
+ this.beanNames = Arrays.asList(beanNames);
+ }
+ /**
+ * Set class name of a TargetSource bean.
+ */
+ public void setTargetClass(String clazz)
+ {
+ this.targetClass = clazz;
+ }
+ /* (non-Javadoc)
+ * @see
org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.spring
framework.beans.factory.BeanFactory)
+ */
+ public void setBeanFactory(BeanFactory beanFactory) throws
BeansException
+ {
+ this.beanFactory = beanFactory;
+ }
+ /* (non-Javadoc)
+ * @see
org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+ */
+ public void afterPropertiesSet() throws Exception
+ {
+ try
+ {
+ if (!StringUtils.isEmpty(targetClass))
+ this.target =
+ (TargetSource) (Class
+ .forName(
+ targetClass,
+ true,
+ this.getClass().getClassLoader()))
+ .newInstance();
+ }
+ catch (Exception exc)
+ {
+ throw new BeanInitializationException(
+ "Invalid targetClass property is specified for bean post
processor "
+ + this.getClass().getName()
+ + "\n"
+ + exc.getMessage());
+ }
+ }
+ /**
+ * Identify as bean to proxy if the bean name is in the configured list
of names.
+ */
+ protected Object[] getInterceptorsAndAdvisorsForBean(
+ Object bean,
+ String beanName)
+ {
+ if (this.beanNames != null)
+ {
+ if (this.beanNames.contains(beanName))
+ {
+ return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
+ }
+ for (Iterator it = this.beanNames.iterator(); it.hasNext();)
+ {
+ String mappedName = (String) it.next();
+ if (isMatch(beanName, mappedName))
+ {
+ return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
+ }
+ }
+ }
+ return DO_NOT_PROXY;
+ }
+ /**
+ * Return if the given bean name matches the mapped name.
+ * The default implementation checks for "xxx*" and "*xxx" matches.
+ * Can be overridden in subclasses.
+ * @param beanName the bean name to check
+ * @param mappedName the name in the configured list of names
+ * @return if the names match
+ */
+ protected boolean isMatch(String beanName, String mappedName)
+ {
+ return (
+ mappedName.endsWith("*")
+ && beanName.startsWith(
+ mappedName.substring(0, mappedName.length() - 1)))
+ || (mappedName.startsWith("*")
+ && beanName.endsWith(
+ mappedName.substring(1, mappedName.length())));
+ }
+ /* (non-Javadoc)
+ * @see
org.springframework.aop.framework.support.AbstractAutoProxyCreator#getTarget
Source(java.lang.Object, java.lang.String)
+ */
+ protected TargetSource getTargetSource(Object bean, String beanName)
+ {
+ if (null == target)
+ {
+ target = super.getTargetSource(bean, beanName);
+ }
+ else if (target instanceof PrototypeTargetSource)
+ {
+ //Infinite cycle: tries to create the bean if we don't use a
different factory
+ //
+ // Create a new registry
+ DefaultListableBeanFactory bf2 = new
DefaultListableBeanFactory();
+ RootBeanDefinition definition;
+ //
+ // define a list of beans that must be registered in the new
registry
+ List depends = new ArrayList();
+ //
+ // add root bean to the dependency list
+ depends.add(beanName);
+ String name;
+ while (depends.size() > 0)
+ {
+ //
+ // get next bean name from the dependency list
+ name = (String) depends.get(0);
+ //
+ // remove it from the dependency list
+ depends.remove(0);
+ //
+ // get bean definition from the original registry
+ definition = ((AbstractBeanFactory) beanFactory)
+ .getMergedBeanDefinition(name,false);
+ // add it to the new registry
+ bf2.registerBeanDefinition(name, definition);
+ //
+ // find all bean references
+ PropertyValues pvs = definition.getPropertyValues();
+ PropertyValue[] pvArray = pvs.getPropertyValues();
+ int len = pvArray.length;
+ int ind;
+ Object val;
+ for (ind = len - 1; ind >= 0; ind--)
+ {
+ name = pvArray[ind].getName();
+ val = pvArray[ind].getValue();
+ if (val instanceof RuntimeBeanReference)
+ {
+ name = ((RuntimeBeanReference) val).getBeanName();
+ //
+ // if a bean reference is not in the new registry
+ // add it to the dependency list
+ if (!bf2.containsBean(name) &&
!depends.contains(name))depends.add(name);
+ }
+ }
+ }
+ ((PrototypeTargetSource) target).setTargetBeanName(beanName);
+ ((PrototypeTargetSource) target).setBeanFactory(bf2);
+ }
+ else
+ {
+ if (!(target instanceof SingletonTargetSource))
+ {
+ logger.warn("TargetSource class [" + targetClass + "] specified in
configuration, is not supported by the BeanNameAutoProxyCreator post
processor. Using SingletonTargetSource instead of the specified
targetClass.");
}
- for (Iterator it = this.beanNames.iterator(); it.hasNext();) {
- String mappedName = (String) it.next();
- if (isMatch(beanName, mappedName)) {
- return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
- }
- }
- }
- return DO_NOT_PROXY;
- }
-
- /**
- * Return if the given bean name matches the mapped name.
- * The default implementation checks for "xxx*" and "*xxx" matches.
- * Can be overridden in subclasses.
- * @param beanName the bean name to check
- * @param mappedName the name in the configured list of names
- * @return if the names match
- */
- protected boolean isMatch(String beanName, String mappedName) {
- return (mappedName.endsWith("*") &&
beanName.startsWith(mappedName.substring(0, mappedName.length() - 1))) ||
- (mappedName.startsWith("*") &&
beanName.endsWith(mappedName.substring(1, mappedName.length())));
- }
-
+ target = super.getTargetSource(bean, beanName);
+ }
+ return target;
+ }
}
----- Original Message -----
From: "Rod Johnson" <rod...@in...>
To: <spr...@li...>
Sent: Thursday, December 04, 2003 2:18 AM
Subject: Re: [Springframework-developer] Configurable TargetSource for
BeanNameAutoProxyCreator
> Hi Rajeev,
>
> Sounds like it might be useful. Can you please send me a CVS patch against
> today's CVS? That way it's easier for me to take a look at it and possibly
> incorporate it.
>
> Regards,
> Rod
>
> ----- Original Message -----
> From: "Rajeev Kaul" <Ra...@cu...>
> To: <spr...@li...>
> Sent: Wednesday, December 03, 2003 8:04 PM
> Subject: [Springframework-developer] Configurable TargetSource for
> BeanNameAutoProxyCreator
>
>
> I wanted the BeanNameAutoProxyCreator class to allow configuration of its
> TargetSource class, so I could easily replace the SingletonTargetSource,
> with other implementations such as, PrototypeTargetSource,
> ThreadLocalTargetSource , etc.
>
> I am submitting a modified version of the BeanNameAutoProxyCreator class
> along with the supporting test files. If you find it useful, you may want
> to include it in the springframework.
>
> Rajeev Kaul
>
>
>
>
> -------------------------------------------------------
> This SF.net email is sponsored by OSDN's Audience Survey.
> Help shape OSDN's sites and tell us what you think. Take this
> five minute survey and you could win a $250 Gift Certificate.
> http://www.wrgsurveys.com/2003/osdntech03.php?site=8
> _______________________________________________
> Springframework-developer mailing list
> Spr...@li...
> https://lists.sourceforge.net/lists/listinfo/springframework-developer
|