parent
522d136bbd
commit
8c4e372558
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -37,6 +37,7 @@ import org.springframework.aop.RawTargetAccess;
|
|||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.CallbackFilter;
|
||||
import org.springframework.cglib.proxy.Dispatcher;
|
||||
|
|
@ -45,7 +46,7 @@ import org.springframework.cglib.proxy.Factory;
|
|||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
import org.springframework.cglib.proxy.NoOp;
|
||||
import org.springframework.cglib.transform.impl.MemorySafeUndeclaredThrowableStrategy;
|
||||
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
|
||||
import org.springframework.core.SmartClassLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
|
@ -183,19 +184,19 @@ class CglibAopProxy implements AopProxy, Serializable {
|
|||
}
|
||||
}
|
||||
enhancer.setSuperclass(proxySuperClass);
|
||||
enhancer.setStrategy(new MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
|
||||
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
|
||||
|
||||
Callback[] callbacks = getCallbacks(rootClass);
|
||||
Class<?>[] types = new Class<?>[callbacks.length];
|
||||
|
||||
for (int x = 0; x < types.length; x++) {
|
||||
types[x] = callbacks[x].getClass();
|
||||
}
|
||||
|
||||
enhancer.setCallbackTypes(types);
|
||||
// fixedInterceptorMap only populated at this point, after getCallbacks call above
|
||||
enhancer.setCallbackFilter(new ProxyCallbackFilter(
|
||||
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
|
||||
enhancer.setCallbackTypes(types);
|
||||
|
||||
// Generate the proxy class and create a proxy instance.
|
||||
return createProxyClassAndInstance(enhancer, callbacks);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -23,7 +23,7 @@ import org.apache.commons.logging.Log;
|
|||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.CallbackFilter;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
|
|
@ -107,6 +107,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
|||
public Object instantiate(Constructor<?> ctor, Object[] args) {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(this.beanDefinition.getBeanClass());
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setCallbackFilter(new CallbackFilterImpl());
|
||||
enhancer.setCallbacks(new Callback[] {
|
||||
NoOp.INSTANCE,
|
||||
|
|
@ -114,9 +115,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
|
|||
new ReplaceOverrideMethodInterceptor()
|
||||
});
|
||||
|
||||
return (ctor == null) ?
|
||||
enhancer.create() :
|
||||
enhancer.create(ctor.getParameterTypes(), args);
|
||||
return (ctor != null ? enhancer.create(ctor.getParameterTypes(), args) : enhancer.create());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -34,6 +34,7 @@ import org.springframework.beans.factory.support.SimpleInstantiationStrategy;
|
|||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.cglib.core.Constants;
|
||||
import org.springframework.cglib.core.DefaultGeneratorStrategy;
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.CallbackFilter;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
|
|
@ -67,6 +68,8 @@ class ConfigurationClassEnhancer {
|
|||
|
||||
private static final ConditionalCallbackFilter CALLBACK_FILTER = new ConditionalCallbackFilter(CALLBACKS);
|
||||
|
||||
private static final DefaultGeneratorStrategy GENERATOR_STRATEGY = new BeanFactoryAwareGeneratorStrategy();
|
||||
|
||||
private static final String BEAN_FACTORY_FIELD = "$$beanFactory";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ConfigurationClassEnhancer.class);
|
||||
|
|
@ -105,22 +108,10 @@ class ConfigurationClassEnhancer {
|
|||
enhancer.setSuperclass(superclass);
|
||||
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
|
||||
enhancer.setUseFactory(false);
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setStrategy(GENERATOR_STRATEGY);
|
||||
enhancer.setCallbackFilter(CALLBACK_FILTER);
|
||||
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
|
||||
enhancer.setStrategy(new DefaultGeneratorStrategy() {
|
||||
@Override
|
||||
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
|
||||
ClassEmitterTransformer transformer = new ClassEmitterTransformer() {
|
||||
@Override
|
||||
public void end_class() {
|
||||
declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD,
|
||||
Type.getType(BeanFactory.class), null);
|
||||
super.end_class();
|
||||
}
|
||||
};
|
||||
return new TransformingClassGenerator(cg, transformer);
|
||||
}
|
||||
});
|
||||
return enhancer;
|
||||
}
|
||||
|
||||
|
|
@ -200,37 +191,27 @@ class ConfigurationClassEnhancer {
|
|||
|
||||
|
||||
/**
|
||||
* Intercepts the invocation of any {@link DisposableBean#destroy()} on @Configuration
|
||||
* class instances for the purpose of de-registering CGLIB callbacks. This helps avoid
|
||||
* garbage collection issues. See SPR-7901.
|
||||
* @see EnhancedConfiguration
|
||||
* Custom extension of CGLIB's DefaultGeneratorStrategy, introducing a {@link BeanFactory} field.
|
||||
*/
|
||||
private static class DisposableBeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
|
||||
private static class BeanFactoryAwareGeneratorStrategy extends DefaultGeneratorStrategy {
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
Enhancer.registerStaticCallbacks(obj.getClass(), null);
|
||||
// Does the actual (non-CGLIB) superclass actually implement DisposableBean?
|
||||
// If so, call its dispose() method. If not, just exit.
|
||||
if (DisposableBean.class.isAssignableFrom(obj.getClass().getSuperclass())) {
|
||||
return proxy.invokeSuper(obj, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatch(Method candidateMethod) {
|
||||
return candidateMethod.getName().equals("destroy") &&
|
||||
candidateMethod.getParameterTypes().length == 0 &&
|
||||
DisposableBean.class.isAssignableFrom(candidateMethod.getDeclaringClass());
|
||||
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
|
||||
ClassEmitterTransformer transformer = new ClassEmitterTransformer() {
|
||||
@Override
|
||||
public void end_class() {
|
||||
declare_field(Constants.ACC_PUBLIC, BEAN_FACTORY_FIELD, Type.getType(BeanFactory.class), null);
|
||||
super.end_class();
|
||||
}
|
||||
};
|
||||
return new TransformingClassGenerator(cg, transformer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Intercepts the invocation of any
|
||||
* {@link BeanFactoryAware#setBeanFactory(BeanFactory)} on {@code @Configuration}
|
||||
* class instances for the purpose of recording the {@link BeanFactory}.
|
||||
* Intercepts the invocation of any {@link BeanFactoryAware#setBeanFactory(BeanFactory)} on
|
||||
* {@code @Configuration} class instances for the purpose of recording the {@link BeanFactory}.
|
||||
* @see EnhancedConfiguration
|
||||
*/
|
||||
private static class BeanFactoryAwareMethodInterceptor implements MethodInterceptor, ConditionalCallback {
|
||||
|
|
@ -387,6 +368,7 @@ class ConfigurationClassEnhancer {
|
|||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(fbClass);
|
||||
enhancer.setUseFactory(false);
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setCallback(new MethodInterceptor() {
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
|
|
@ -404,7 +386,8 @@ class ConfigurationClassEnhancer {
|
|||
Assert.state(field != null, "Unable to find generated bean factory field");
|
||||
Object beanFactory = ReflectionUtils.getField(field, enhancedConfigInstance);
|
||||
Assert.state(beanFactory != null, "BeanFactory has not been injected into @Configuration class");
|
||||
Assert.state(beanFactory instanceof ConfigurableBeanFactory, "Injected BeanFactory is not a ConfigurableBeanFactory");
|
||||
Assert.state(beanFactory instanceof ConfigurableBeanFactory,
|
||||
"Injected BeanFactory is not a ConfigurableBeanFactory");
|
||||
return (ConfigurableBeanFactory) beanFactory;
|
||||
}
|
||||
|
||||
|
|
@ -414,4 +397,32 @@ class ConfigurationClassEnhancer {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Intercepts the invocation of any {@link DisposableBean#destroy()} on @Configuration
|
||||
* class instances for the purpose of de-registering CGLIB callbacks. This helps avoid
|
||||
* garbage collection issues. See SPR-7901.
|
||||
* @see EnhancedConfiguration
|
||||
*/
|
||||
private static class DisposableBeanMethodInterceptor implements MethodInterceptor, ConditionalCallback {
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
Enhancer.registerStaticCallbacks(obj.getClass(), null);
|
||||
// Does the actual (non-CGLIB) superclass actually implement DisposableBean?
|
||||
// If so, call its dispose() method. If not, just exit.
|
||||
if (DisposableBean.class.isAssignableFrom(obj.getClass().getSuperclass())) {
|
||||
return proxy.invokeSuper(obj, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatch(Method candidateMethod) {
|
||||
return candidateMethod.getName().equals("destroy") &&
|
||||
candidateMethod.getParameterTypes().length == 0 &&
|
||||
DisposableBean.class.isAssignableFrom(candidateMethod.getDeclaringClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2002-2014 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 org.springframework.cglib.core;
|
||||
|
||||
/**
|
||||
* Custom extension of CGLIB's {@link DefaultNamingPolicy}, modifying
|
||||
* the tag in generated class names from "ByCGLIB" to "BySpringCGLIB".
|
||||
*
|
||||
* <p>This is primarily designed to avoid clashes between a regular CGLIB
|
||||
* version (used by some other library) and Spring's embedded variant,
|
||||
* in case the same class happens to get proxied for different purposes.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.2.8
|
||||
*/
|
||||
public class SpringNamingPolicy extends DefaultNamingPolicy {
|
||||
|
||||
public static final SpringNamingPolicy INSTANCE = new SpringNamingPolicy();
|
||||
|
||||
@Override
|
||||
protected String getTag() {
|
||||
return "BySpringCGLIB";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 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 org.springframework.cglib.transform.impl;
|
||||
|
||||
import org.springframework.cglib.core.ClassGenerator;
|
||||
import org.springframework.cglib.core.DefaultGeneratorStrategy;
|
||||
import org.springframework.cglib.core.TypeUtils;
|
||||
import org.springframework.cglib.transform.ClassTransformer;
|
||||
import org.springframework.cglib.transform.MethodFilter;
|
||||
import org.springframework.cglib.transform.MethodFilterTransformer;
|
||||
import org.springframework.cglib.transform.TransformingClassGenerator;
|
||||
|
||||
/**
|
||||
* Memory safe variant of {@link UndeclaredThrowableStrategy} ported from the latest
|
||||
* as yet unreleased cglib code.
|
||||
*/
|
||||
public class MemorySafeUndeclaredThrowableStrategy extends DefaultGeneratorStrategy {
|
||||
|
||||
private static final MethodFilter TRANSFORM_FILTER = new MethodFilter() {
|
||||
public boolean accept(int access, String name, String desc, String signature,
|
||||
String[] exceptions) {
|
||||
return !TypeUtils.isPrivate(access) && name.indexOf('$') < 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private Class<?> wrapper;
|
||||
|
||||
|
||||
public MemorySafeUndeclaredThrowableStrategy(Class<?> wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
|
||||
protected ClassGenerator transform(ClassGenerator cg) throws Exception {
|
||||
ClassTransformer tr = new UndeclaredThrowableTransformer(wrapper);
|
||||
tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
|
||||
return new TransformingClassGenerator(cg, tr);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
|
|
@ -29,6 +29,7 @@ import org.apache.commons.logging.LogFactory;
|
|||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.target.EmptyTargetSource;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.cglib.core.SpringNamingPolicy;
|
||||
import org.springframework.cglib.proxy.Callback;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
import org.springframework.cglib.proxy.Factory;
|
||||
|
|
@ -72,16 +73,15 @@ public class MvcUriComponentsBuilder extends UriComponentsBuilder {
|
|||
public static final String MVC_URI_COMPONENTS_CONTRIBUTOR_BEAN_NAME = "mvcUriComponentsContributor";
|
||||
|
||||
|
||||
private static final CompositeUriComponentsContributor defaultUriComponentsContributor;
|
||||
private static final Log logger = LogFactory.getLog(MvcUriComponentsBuilder.class);
|
||||
|
||||
private static final ObjenesisStd objenesis = new ObjenesisStd(true);
|
||||
|
||||
private static final PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
private static final ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
|
||||
|
||||
private static final ObjenesisStd objenesis = new ObjenesisStd(true);
|
||||
|
||||
private static final Log logger = LogFactory.getLog(MvcUriComponentsBuilder.class);
|
||||
|
||||
private static final CompositeUriComponentsContributor defaultUriComponentsContributor;
|
||||
|
||||
static {
|
||||
defaultUriComponentsContributor = new CompositeUriComponentsContributor(
|
||||
|
|
@ -341,7 +341,8 @@ public class MvcUriComponentsBuilder extends UriComponentsBuilder {
|
|||
else {
|
||||
Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(type);
|
||||
enhancer.setInterfaces(new Class<?>[]{MethodInvocationInfo.class});
|
||||
enhancer.setInterfaces(new Class<?>[] {MethodInvocationInfo.class});
|
||||
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
|
||||
enhancer.setCallbackType(org.springframework.cglib.proxy.MethodInterceptor.class);
|
||||
Factory factory = (Factory) objenesis.newInstance(enhancer.createClass());
|
||||
factory.setCallbacks(new Callback[] {interceptor});
|
||||
|
|
|
|||
Loading…
Reference in New Issue