Browse Source

Introduced SpringNamingPolicy for CGLIB

Issue: SPR-11398
(cherry picked from commit 8c4e372)
pull/465/head
Juergen Hoeller 12 years ago
parent
commit
f558396e91
  1. 31
      spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
  2. 13
      spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java
  3. 6
      spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java
  4. 12
      spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java
  5. 39
      spring-core/src/main/java/org/springframework/cglib/core/SpringNamingPolicy.java
  6. 15
      spring-core/src/main/java/org/springframework/cglib/transform/impl/MemorySafeUndeclaredThrowableStrategy.java

31
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

@ -1,5 +1,5 @@ @@ -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; @@ -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;
@ -181,20 +182,20 @@ final class CglibAopProxy implements AopProxy, Serializable { @@ -181,20 +182,20 @@ final 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 MemorySafeUndeclaredThrowableStrategy(UndeclaredThrowableException.class));
enhancer.setInterceptDuringConstruction(false);
Callback[] callbacks = getCallbacks(rootClass);
enhancer.setCallbacks(callbacks);
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
Class<?>[] types = new Class[callbacks.length];
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
enhancer.setCallbacks(callbacks);
// Generate the proxy class and create a proxy instance.
Object proxy;
@ -312,8 +313,7 @@ final class CglibAopProxy implements AopProxy, Serializable { @@ -312,8 +313,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<String, Integer>(methods.length);
// TODO: small memory optimisation here (can skip creation for
// methods with no advice)
// TODO: small memory optimisation here (can skip creation for methods with no advice)
for (int x = 0; x < methods.length; x++) {
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
@ -340,16 +340,15 @@ final class CglibAopProxy implements AopProxy, Serializable { @@ -340,16 +340,15 @@ final class CglibAopProxy implements AopProxy, Serializable {
*/
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) {
// Massage return value if necessary
if (retVal != null && retVal == target &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this".
// Note that we can't help if the target sets a reference
// to itself in another returned object.
if (retVal != null && retVal == target && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this". Note that we can't help
// if the target sets a reference to itself in another returned object.
retVal = proxy;
}
Class<?> returnType = method.getReturnType();
if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
@ -851,7 +850,7 @@ final class CglibAopProxy implements AopProxy, Serializable { @@ -851,7 +850,7 @@ final class CglibAopProxy implements AopProxy, Serializable {
@Override
public boolean equals(Object other) {
if (other == this) {
if (this == other) {
return true;
}
if (!(other instanceof ProxyCallbackFilter)) {

13
spring-beans/src/main/java/org/springframework/beans/factory/support/CglibSubclassingInstantiationStrategy.java

@ -1,5 +1,5 @@ @@ -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; @@ -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;
@ -72,7 +72,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt @@ -72,7 +72,7 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
@Override
protected Object instantiateWithMethodInjection(
RootBeanDefinition beanDefinition, String beanName, BeanFactory owner,
Constructor ctor, Object[] args) {
Constructor<?> ctor, Object[] args) {
return new CglibSubclassCreator(beanDefinition, owner).instantiate(ctor, args);
}
@ -104,9 +104,10 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt @@ -104,9 +104,10 @@ public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationSt
* Ignored if the ctor parameter is {@code null}.
* @return new instance of the dynamically generated class
*/
public Object instantiate(Constructor ctor, Object[] args) {
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 @@ -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());
}

6
spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleInstantiationStrategy.java

@ -62,14 +62,14 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { @@ -62,14 +62,14 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
synchronized (beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class clazz = beanDefinition.getBeanClass();
final Class<?> clazz = beanDefinition.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
public Constructor run() throws Exception {
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
@ -132,7 +132,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy { @@ -132,7 +132,7 @@ public class SimpleInstantiationStrategy implements InstantiationStrategy {
* Instantiation should use the given constructor and parameters.
*/
protected Object instantiateWithMethodInjection(RootBeanDefinition beanDefinition,
String beanName, BeanFactory owner, Constructor ctor, Object[] args) {
String beanName, BeanFactory owner, Constructor<?> ctor, Object[] args) {
throw new UnsupportedOperationException(
"Method Injection not supported in SimpleInstantiationStrategy");

12
spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassEnhancer.java

@ -1,5 +1,5 @@ @@ -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.springframework.beans.factory.FactoryBean; @@ -29,6 +29,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.SimpleInstantiationStrategy;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.CallbackFilter;
import org.springframework.cglib.proxy.Enhancer;
@ -103,8 +104,9 @@ class ConfigurationClassEnhancer { @@ -103,8 +104,9 @@ class ConfigurationClassEnhancer {
private Enhancer newEnhancer(Class<?> superclass) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(superclass);
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setInterfaces(new Class<?>[]{EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer;
@ -128,9 +130,9 @@ class ConfigurationClassEnhancer { @@ -128,9 +130,9 @@ class ConfigurationClassEnhancer {
* Facilitates idempotent behavior for {@link ConfigurationClassEnhancer#enhance(Class)}
* through checking to see if candidate classes are already assignable to it, e.g.
* have already been enhanced.
* <p>Also extends {@link DisposableBean}, as all enhanced
* {@code @Configuration} classes must de-register static CGLIB callbacks on
* destruction, which is handled by the (private) {@code DisposableBeanMethodInterceptor}.
* <p>Also extends {@link DisposableBean}, as all enhanced {@code @Configuration}
* classes must de-register static CGLIB callbacks on destruction, which is handled
* by the (private) {@code DisposableBeanMethodInterceptor}.
* <p>Note that this interface is intended for framework-internal use only, however
* must remain public in order to allow access to subclasses generated from other
* packages (i.e. user code).

39
spring-core/src/main/java/org/springframework/cglib/core/SpringNamingPolicy.java

@ -0,0 +1,39 @@ @@ -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";
}
}

15
spring-core/src/main/java/org/springframework/cglib/transform/impl/MemorySafeUndeclaredThrowableStrategy.java

@ -1,5 +1,5 @@ @@ -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.
@ -25,20 +25,22 @@ import org.springframework.cglib.transform.MethodFilterTransformer; @@ -25,20 +25,22 @@ 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.
* Memory-safe variant of {@link UndeclaredThrowableStrategy} ported from the latest
* as yet unreleased CGLIB code.
*
* @author Phillip Webb
* @since 3.2.4
*/
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) {
public boolean accept(int access, String name, String desc, String signature, String[] exceptions) {
return !TypeUtils.isPrivate(access) && name.indexOf('$') < 0;
}
};
private Class wrapper;
private Class<?> wrapper;
public MemorySafeUndeclaredThrowableStrategy(Class wrapper) {
@ -51,4 +53,5 @@ public class MemorySafeUndeclaredThrowableStrategy extends DefaultGeneratorStrat @@ -51,4 +53,5 @@ public class MemorySafeUndeclaredThrowableStrategy extends DefaultGeneratorStrat
tr = new MethodFilterTransformer(TRANSFORM_FILTER, tr);
return new TransformingClassGenerator(cg, tr);
}
}

Loading…
Cancel
Save