⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 valuebindingresolvinginstantiationstrategy.java

📁 Please read your package and describe it at least 40 bytes in English. System will automatically de
💻 JAVA
字号:
/* * Copyright 2002-2004 the original author or authors. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package de.mindmatters.faces.spring.factory;import java.lang.reflect.Constructor;import java.lang.reflect.Method;import javax.faces.context.FacesContext;import net.sf.cglib.proxy.Callback;import net.sf.cglib.proxy.CallbackFilter;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;import net.sf.cglib.proxy.NoOp;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.springframework.beans.factory.BeanFactory;import org.springframework.beans.factory.support.LookupOverride;import org.springframework.beans.factory.support.MethodOverride;import org.springframework.beans.factory.support.MethodReplacer;import org.springframework.beans.factory.support.ReplaceOverride;import org.springframework.beans.factory.support.RootBeanDefinition;import org.springframework.beans.factory.support.SimpleInstantiationStrategy;import org.springframework.util.Assert;import de.mindmatters.faces.FacesUtils;/** * Default object instantiation strategy for use in ManagedBeanFactories which * resolves value bindings for replace- and lookup-methods. Uses CGLIB to * generate subclasses dynamically if methods need to be overridden by the * container to implement Method Injection. *  * @author Andreas Kuhrwahl */public final class ValueBindingResolvingInstantiationStrategy extends        SimpleInstantiationStrategy {    /**     * An inner class so we don't have a CGLIB dependency in core.     */    private static class CglibSubclassCreator {        /**         * Index in the CGLIB callback array for passthrough behavior, in which         * case the subclass won't override the original class.         */        private static final int PASSTHROUGH = 0;        /**         * Index in the CGLIB callback array for a method that should be         * overridden to provide method lookup.         */        private static final int LOOKUP_OVERRIDE = 1;        /**         * Index in the CGLIB callback array for a method that should be         * overridden using generic Methodreplacer functionality.         */        private static final int METHOD_REPLACER = 2;        /**         * Class providing hashCode and equals methods required by CGLIB to         * ensure that CGLIB doesn't generate a distinct class per bean.         * Identity is based on class and bean name.         *          * @author Andreas Kuhrwahl         */        private class CglibIdentitySupport {            /**             * Exposed for equals method to allow access to enclosing class             * field.             *              * @return The encapsulated RootBeanDefinition             */            private RootBeanDefinition getBeanDefinition() {                return beanDefinition;            }            /**             * Provided hashCode required by CGLIB to ensure that CGLIB doesn't             * generate a distinct class per bean.             *              * @return a hash code value for this object.             */            public final int hashCode() {                return beanDefinition.hashCode();            }            /**             * Provided equals method required by CGLIB to ensure that CGLIB             * doesn't generate a distinct class per bean.             *              * @param other             *            the reference object with which to compare.             * @return <code>true</code> if this object is the same as the obj             *         argument; <code>false</code> otherwise.             */            public final boolean equals(final Object other) {                return (other.getClass() == getClass())                        && ((CglibIdentitySupport) other).getBeanDefinition() == beanDefinition;            }        }        /**         * CGLIB object to filter method interception behavior.         */        private class CallbackFilterImpl extends CglibIdentitySupport implements                CallbackFilter {            /**             * {@inheritDoc}             */            public int accept(final Method method) {                final MethodOverride methodOverride = beanDefinition                        .getMethodOverrides().getOverride(method);                if (logger.isDebugEnabled()) {                    logger.debug("Override for '" + method.getName() + "' is ["                            + methodOverride + "]");                }                int returnCode;                if (methodOverride == null) {                    returnCode = PASSTHROUGH;                } else if (methodOverride instanceof LookupOverride) {                    returnCode = LOOKUP_OVERRIDE;                } else if (methodOverride instanceof ReplaceOverride) {                    returnCode = METHOD_REPLACER;                } else {                    throw new UnsupportedOperationException(                            "Unexpected MethodOverride subclass: "                                    + methodOverride.getClass().getName());                }                return returnCode;            }        }        /**         * CGLIB MethodInterceptor to override methods, replacing them with an         * implementation that returns a bean looked up in the container or         * resolved by a value binding.         */        private class LookupOverrideMethodInterceptor extends                CglibIdentitySupport implements MethodInterceptor {            /**             * {@inheritDoc}             */            public Object intercept(final Object obj, final Method method,                    final Object[] args, final MethodProxy mp) throws Throwable {                final LookupOverride lo = (LookupOverride) beanDefinition                        .getMethodOverrides().getOverride(method);                final FacesContext context = getFacesContext();                Object bean = null;                if (FacesUtils.isValueReference(lo.getBeanName())) {                    bean = context.getApplication().createValueBinding(                            lo.getBeanName()).getValue(context);                } else {                    bean = owner.getBean(lo.getBeanName());                }                return bean;            }        }        /**         * CGLIB MethodInterceptor to override methods, replacing them with a         * call to a generic MethodReplacer (maybe resolved by a value binding).         */        private class ReplaceOverrideMethodInterceptor extends                CglibIdentitySupport implements MethodInterceptor {            /**             * {@inheritDoc}             */            public Object intercept(final Object obj, final Method method,                    final Object[] args, final MethodProxy mp) throws Throwable {                final ReplaceOverride ro = (ReplaceOverride) beanDefinition                        .getMethodOverrides().getOverride(method);                MethodReplacer mr = null;                final FacesContext context = getFacesContext();                if (FacesUtils.isValueReference(ro                        .getMethodReplacerBeanName())) {                    mr = (MethodReplacer) context.getApplication()                            .createValueBinding(ro.getMethodReplacerBeanName())                            .getValue(context);                } else {                    mr = (MethodReplacer) owner.getBean(ro                            .getMethodReplacerBeanName());                }                return mr.reimplement(obj, method, args);            }        }        /** For logging. */        private final Log logger = LogFactory.getLog(getClass());        /** The BeanDefinition subclasses are created for. */        private final RootBeanDefinition beanDefinition;        /** The owning BeanFactory. */        private final BeanFactory owner;        /**         * Creates a subclass creator based on CGLib.         *          * @param beanDefinition         *            The BeanDefinition subclasses are created for.         * @param owner         *            The owning BeanFactory.         */        public CglibSubclassCreator(final RootBeanDefinition beanDefinition,                final BeanFactory owner) {            this.beanDefinition = beanDefinition;            this.owner = owner;        }        /**         * @return the current instance of the FacesContext         */        private FacesContext getFacesContext() {            final FacesContext context = FacesContext.getCurrentInstance();            Assert.notNull(context, "no faces-context");            return context;        }        /**         * Create a new instance of a dynamically generated subclasses         * implementing the required lookups.         *          * @param ctor         *            constructor to use. If this is <code>null</code>, use         *            the no-arg constructor (no parameterization, or Setter         *            Injection)         * @param args         *            arguments to use for the constructor. Ignored if the ctor         *            parameter is <code>null</code>.         * @return new instance of the dynamically generated class         */        public Object instantiate(final Constructor ctor, final Object[] args) {            Enhancer enhancer = new Enhancer();            enhancer.setSuperclass(this.beanDefinition.getBeanClass());            enhancer.setCallbackFilter(new CallbackFilterImpl());            enhancer.setCallbacks(new Callback[] { NoOp.INSTANCE,                    new LookupOverrideMethodInterceptor(),                    new ReplaceOverrideMethodInterceptor() });            Object result = null;            if (ctor == null) {                result = enhancer.create();            } else {                result = enhancer.create(ctor.getParameterTypes(), args);            }            return result;        }    }    /**     * {@inheritDoc}     */    protected Object instantiateWithMethodInjection(            final RootBeanDefinition beanDefinition, final String beanName,            final BeanFactory owner) {        return new CglibSubclassCreator(beanDefinition, owner).instantiate(                null, null);    }    /**     * {@inheritDoc}     */    protected Object instantiateWithMethodInjection(            final RootBeanDefinition beanDefinition, final String beanName,            final BeanFactory owner, final Constructor ctor, final Object[] args) {        return new CglibSubclassCreator(beanDefinition, owner).instantiate(                ctor, args);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -