/** * Validate and prepare the method overrides defined for this bean. * Checks for existence of a method with the specified name. * @throws BeanDefinitionValidationException in case of validation failure */ public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. if (hasMethodOverrides()) { Set<MethodOverride> overrides = getMethodOverrides().getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { prepareMethodOverride(mo); } } } }
/** * Parse lookup-override sub-elements of the given bean element. */ public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) { Element ele = (Element) node; String methodName = ele.getAttribute(NAME_ATTRIBUTE); String beanRef = ele.getAttribute(BEAN_ELEMENT); LookupOverride override = new LookupOverride(methodName, beanRef); override.setSource(extractSource(ele)); overrides.addOverride(override); } } }
/** * Deep copy constructor. */ public MethodOverrides(MethodOverrides other) { addOverrides(other); }
@Override public int accept(Method method) { MethodOverride methodOverride = getBeanDefinition().getMethodOverrides().getOverride(method); if (logger.isTraceEnabled()) { logger.trace("Override for '" + method.getName() + "' is [" + methodOverride + "]"); } if (methodOverride == null) { return PASSTHROUGH; } else if (methodOverride instanceof LookupOverride) { return LOOKUP_OVERRIDE; } else if (methodOverride instanceof ReplaceOverride) { return METHOD_REPLACER; } throw new UnsupportedOperationException("Unexpected MethodOverride subclass: " + methodOverride.getClass().getName()); } }
/** * Validate and prepare the method overrides defined for this bean. * Checks for existence of a method with the specified name. * @throws BeanDefinitionValidationException in case of validation failure */ public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. MethodOverrides methodOverrides = getMethodOverrides(); if (!methodOverrides.isEmpty()) { for (MethodOverride mo : methodOverrides.getOverrides()) { prepareMethodOverride(mo); } } }
private void addMethodOverrides(final AbstractBeanDefinition beanDefinition, final Class<?> clazz) { final MethodOverrides methodOverrides = beanDefinition.getMethodOverrides(); for (final Method method : clazz.getMethods()) { if (Modifier.isAbstract(method.getModifiers()) && methodOverrides.getOverride(method) == null) { LOGGER.info("Add override for {}.", method); methodOverrides.addOverride(new ReplaceOverride(method.getName(), UNSUPPORTED_METHOD_REPLACER_NAME)); } } }
/** * Return if there are method overrides defined for this bean. * @since 5.0.2 */ public boolean hasMethodOverrides() { return (this.methodOverrides != null && !this.methodOverrides.isEmpty()); }
/** * Return information about methods to be overridden by the IoC * container. This will be empty if there are no method overrides. * <p>Never returns {@code null}. */ public MethodOverrides getMethodOverrides() { if (this.methodOverrides == null) { this.methodOverrides = new MethodOverrides(); } return this.methodOverrides; }
@Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable { // Cast is safe, as CallbackFilter filters are used selectively. LookupOverride lo = (LookupOverride) getBeanDefinition().getMethodOverrides().getOverride(method); Assert.state(lo != null, "LookupOverride not found"); Object[] argsToUse = (args.length > 0 ? args : null); // if no-arg, don't insist on args at all if (StringUtils.hasText(lo.getBeanName())) { return (argsToUse != null ? this.owner.getBean(lo.getBeanName(), argsToUse) : this.owner.getBean(lo.getBeanName())); } else { return (argsToUse != null ? this.owner.getBean(method.getReturnType(), argsToUse) : this.owner.getBean(method.getReturnType())); } } }
/** * Validate this bean definition. * @throws BeanDefinitionValidationException in case of validation failure */ public void validate() throws BeanDefinitionValidationException { if (this.lazyInit && !this.singleton) { throw new BeanDefinitionValidationException( "Lazy initialization is only applicable to singleton beans"); } if (!getMethodOverrides().isEmpty() && getFactoryMethodName() != null) { throw new BeanDefinitionValidationException( "Cannot combine static factory method with method overrides: " + "the static factory method must create the instance"); } if (hasBeanClass()) { // Check that lookup methods exists for (Iterator it = getMethodOverrides().getOverrides().iterator(); it.hasNext(); ) { MethodOverride mo = (MethodOverride) it.next(); validateMethodOverride(mo); } } }
/** * Return if there are method overrides defined for this bean. * @since 5.0.2 */ public boolean hasMethodOverrides() { return (this.methodOverrides != null && !this.methodOverrides.isEmpty()); }
/** * Return information about methods to be overridden by the IoC * container. This will be empty if there are no method overrides. * <p>Never returns {@code null}. */ public MethodOverrides getMethodOverrides() { if (this.methodOverrides == null) { this.methodOverrides = new MethodOverrides(); } return this.methodOverrides; }
/** * Validate and prepare the method overrides defined for this bean. * Checks for existence of a method with the specified name. * @throws BeanDefinitionValidationException in case of validation failure */ public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. if (hasMethodOverrides()) { Set<MethodOverride> overrides = getMethodOverrides().getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { prepareMethodOverride(mo); } } } }
/** * Parse replaced-method sub-elements of the given bean element. */ public void parseReplacedMethodSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, REPLACED_METHOD_ELEMENT)) { Element replacedMethodEle = (Element) node; String name = replacedMethodEle.getAttribute(NAME_ATTRIBUTE); String callback = replacedMethodEle.getAttribute(REPLACER_ATTRIBUTE); ReplaceOverride replaceOverride = new ReplaceOverride(name, callback); // Look for arg-type match elements. List<Element> argTypeEles = DomUtils.getChildElementsByTagName(replacedMethodEle, ARG_TYPE_ELEMENT); for (Element argTypeEle : argTypeEles) { String match = argTypeEle.getAttribute(ARG_TYPE_MATCH_ATTRIBUTE); match = (StringUtils.hasText(match) ? match : DomUtils.getTextValue(argTypeEle)); if (StringUtils.hasText(match)) { replaceOverride.addTypeIdentifier(match); } } replaceOverride.setSource(extractSource(replacedMethodEle)); overrides.addOverride(replaceOverride); } } }
@Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy mp) throws Throwable { ReplaceOverride ro = (ReplaceOverride) getBeanDefinition().getMethodOverrides().getOverride(method); Assert.state(ro != null, "ReplaceOverride not found"); // TODO could cache if a singleton for minor performance optimization MethodReplacer mr = this.owner.getBean(ro.getMethodReplacerBeanName(), MethodReplacer.class); return mr.reimplement(obj, method, args); } }
/** * Deep copy constructor. */ public MethodOverrides(MethodOverrides other) { addOverrides(other); }
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner, final Constructor<?> ctor, Object[] args) { if (beanDefinition.getMethodOverrides().isEmpty()) { if (System.getSecurityManager() != null) { // use own privileged to change accessibility (when security is on) AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { ReflectionUtils.makeAccessible(ctor); return null; } }); } return BeanUtils.instantiateClass(ctor, args); } else { return instantiateWithMethodInjection(beanDefinition, beanName, owner, ctor, args); } }
/** * Specify method overrides for the bean, if any. */ public void setMethodOverrides(MethodOverrides methodOverrides) { this.methodOverrides = (methodOverrides != null ? methodOverrides : new MethodOverrides()); }
/** * @since 3.2.8 * @see <a href="https://jira.spring.io/browse/SPR-11420">SPR-11420</a> */ @Test public void rootBeanDefinitionAndMethodOverridesWithDifferentOverloadedValues() { RootBeanDefinition master = new RootBeanDefinition(TestBean.class); RootBeanDefinition equal = new RootBeanDefinition(TestBean.class); setBaseProperties(master); setBaseProperties(equal); // Simulate AbstractBeanDefinition.validate() which delegates to // AbstractBeanDefinition.prepareMethodOverrides(): master.getMethodOverrides().getOverrides().iterator().next().setOverloaded(false); // But do not simulate validation of the 'equal' bean. As a consequence, a method // override in 'equal' will be marked as overloaded, but the corresponding // override in 'master' will not. But... the bean definitions should still be // considered equal. assertEquals("Should be equal", master, equal); assertEquals("Hash code for equal instances must match", master.hashCode(), equal.hashCode()); }
/** * Parse lookup-override sub-elements of the given bean element. */ public void parseLookupOverrideSubElements(Element beanEle, MethodOverrides overrides) { NodeList nl = beanEle.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (isCandidateElement(node) && nodeNameEquals(node, LOOKUP_METHOD_ELEMENT)) { Element ele = (Element) node; String methodName = ele.getAttribute(NAME_ATTRIBUTE); String beanRef = ele.getAttribute(BEAN_ELEMENT); LookupOverride override = new LookupOverride(methodName, beanRef); override.setSource(extractSource(ele)); overrides.addOverride(override); } } }