Merge branch '5.3.x'
# Conflicts: # build.gradle # spring-jms/src/main/java/org/springframework/jms/connection/CachingConnectionFactory.java
This commit is contained in:
commit
aa48dec697
20
build.gradle
20
build.gradle
|
@ -27,7 +27,7 @@ configure(allprojects) { project ->
|
|||
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.13.1"
|
||||
mavenBom "com.fasterxml.jackson:jackson-bom:2.13.3"
|
||||
mavenBom "io.netty:netty-bom:4.1.77.Final"
|
||||
mavenBom "io.projectreactor:reactor-bom:2022.0.0-M2"
|
||||
mavenBom "io.r2dbc:r2dbc-bom:Borca-SR1"
|
||||
|
@ -86,9 +86,9 @@ configure(allprojects) { project ->
|
|||
dependency "org.ogce:xpp3:1.1.6"
|
||||
dependency "org.yaml:snakeyaml:1.30"
|
||||
|
||||
dependency "com.h2database:h2:2.1.210"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:3.1.0"
|
||||
dependency "com.github.librepdf:openpdf:1.3.27"
|
||||
dependency "com.h2database:h2:2.1.212"
|
||||
dependency "com.github.ben-manes.caffeine:caffeine:3.1.1"
|
||||
dependency "com.github.librepdf:openpdf:1.3.28"
|
||||
dependency "com.rometools:rome:1.18.0"
|
||||
dependency "commons-io:commons-io:2.11.0"
|
||||
dependency "io.vavr:vavr:0.10.4"
|
||||
|
@ -117,14 +117,14 @@ configure(allprojects) { project ->
|
|||
dependency "org.webjars:webjars-locator-core:0.48"
|
||||
dependency "org.webjars:underscorejs:1.8.3"
|
||||
|
||||
dependencySet(group: 'org.apache.tomcat', version: '10.0.20') {
|
||||
dependencySet(group: 'org.apache.tomcat', version: '10.0.22') {
|
||||
entry 'tomcat-util'
|
||||
entry('tomcat-websocket') {
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-servlet-api"
|
||||
exclude group: "org.apache.tomcat", name: "tomcat-websocket-api"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.20') {
|
||||
dependencySet(group: 'org.apache.tomcat.embed', version: '10.0.22') {
|
||||
entry 'tomcat-embed-core'
|
||||
entry 'tomcat-embed-websocket'
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ configure(allprojects) { project ->
|
|||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
}
|
||||
dependencySet(group: 'org.mockito', version: '4.5.1') {
|
||||
dependencySet(group: 'org.mockito', version: '4.6.1') {
|
||||
entry('mockito-core') {
|
||||
exclude group: "org.hamcrest", name: "hamcrest-core"
|
||||
}
|
||||
|
@ -185,10 +185,10 @@ configure(allprojects) { project ->
|
|||
}
|
||||
dependency "io.mockk:mockk:1.12.1"
|
||||
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.61.0") {
|
||||
dependency("net.sourceforge.htmlunit:htmlunit:2.62.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.61.0") {
|
||||
dependency("org.seleniumhq.selenium:htmlunit-driver:2.62.0") {
|
||||
exclude group: "commons-logging", name: "commons-logging"
|
||||
}
|
||||
dependency("org.seleniumhq.selenium:selenium-java:3.141.59") {
|
||||
|
@ -299,7 +299,7 @@ configure([rootProject] + javaProjects) { project ->
|
|||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.1"
|
||||
toolVersion = "10.3"
|
||||
configDirectory.set(rootProject.file("src/checkstyle"))
|
||||
}
|
||||
|
||||
|
|
|
@ -86,8 +86,7 @@ jar {
|
|||
dependsOn cglibRepackJar
|
||||
from(zipTree(cglibRepackJar.archivePath)) {
|
||||
include "org/springframework/cglib/**"
|
||||
exclude "org/springframework/cglib/beans/BeanMap.class"
|
||||
exclude "org/springframework/cglib/beans/BeanMap\$*.class"
|
||||
exclude "org/springframework/cglib/beans/**"
|
||||
exclude "org/springframework/cglib/core/AbstractClassGenerator*.class"
|
||||
exclude "org/springframework/cglib/core/AsmApi*.class"
|
||||
exclude "org/springframework/cglib/core/KeyFactory.class"
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* Copyright 2003,2004 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.*;
|
||||
import java.security.ProtectionDomain;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
abstract public class BeanCopier
|
||||
{
|
||||
private static final BeanCopierKey KEY_FACTORY =
|
||||
(BeanCopierKey)KeyFactory.create(BeanCopierKey.class);
|
||||
private static final Type CONVERTER =
|
||||
TypeUtils.parseType("org.springframework.cglib.core.Converter");
|
||||
private static final Type BEAN_COPIER =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BeanCopier");
|
||||
private static final Signature COPY =
|
||||
new Signature("copy", Type.VOID_TYPE, new Type[]{ Constants.TYPE_OBJECT, Constants.TYPE_OBJECT, CONVERTER });
|
||||
private static final Signature CONVERT =
|
||||
TypeUtils.parseSignature("Object convert(Object, Class, Object)");
|
||||
|
||||
interface BeanCopierKey {
|
||||
public Object newInstance(String source, String target, boolean useConverter);
|
||||
}
|
||||
|
||||
public static BeanCopier create(Class source, Class target, boolean useConverter) {
|
||||
Generator gen = new Generator();
|
||||
gen.setSource(source);
|
||||
gen.setTarget(target);
|
||||
gen.setUseConverter(useConverter);
|
||||
return gen.create();
|
||||
}
|
||||
|
||||
abstract public void copy(Object from, Object to, Converter converter);
|
||||
|
||||
public static class Generator extends AbstractClassGenerator {
|
||||
private static final Source SOURCE = new Source(BeanCopier.class.getName());
|
||||
private Class source;
|
||||
private Class target;
|
||||
private boolean useConverter;
|
||||
|
||||
public Generator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
|
||||
public void setSource(Class source) {
|
||||
if(!Modifier.isPublic(source.getModifiers())){
|
||||
setNamePrefix(source.getName());
|
||||
}
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public void setTarget(Class target) {
|
||||
if(!Modifier.isPublic(target.getModifiers())){
|
||||
setNamePrefix(target.getName());
|
||||
}
|
||||
this.target = target;
|
||||
// SPRING PATCH BEGIN
|
||||
setContextClass(target);
|
||||
// SPRING PATCH END
|
||||
}
|
||||
|
||||
public void setUseConverter(boolean useConverter) {
|
||||
this.useConverter = useConverter;
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return source.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(source);
|
||||
}
|
||||
|
||||
public BeanCopier create() {
|
||||
Object key = KEY_FACTORY.newInstance(source.getName(), target.getName(), useConverter);
|
||||
return (BeanCopier)super.create(key);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
Type sourceType = Type.getType(source);
|
||||
Type targetType = Type.getType(target);
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
ce.begin_class(Constants.V1_8,
|
||||
Constants.ACC_PUBLIC,
|
||||
getClassName(),
|
||||
BEAN_COPIER,
|
||||
null,
|
||||
Constants.SOURCE_FILE);
|
||||
|
||||
EmitUtils.null_constructor(ce);
|
||||
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, COPY, null);
|
||||
PropertyDescriptor[] getters = ReflectUtils.getBeanGetters(source);
|
||||
PropertyDescriptor[] setters = ReflectUtils.getBeanSetters(target);
|
||||
|
||||
Map names = new HashMap();
|
||||
for (int i = 0; i < getters.length; i++) {
|
||||
names.put(getters[i].getName(), getters[i]);
|
||||
}
|
||||
Local targetLocal = e.make_local();
|
||||
Local sourceLocal = e.make_local();
|
||||
if (useConverter) {
|
||||
e.load_arg(1);
|
||||
e.checkcast(targetType);
|
||||
e.store_local(targetLocal);
|
||||
e.load_arg(0);
|
||||
e.checkcast(sourceType);
|
||||
e.store_local(sourceLocal);
|
||||
} else {
|
||||
e.load_arg(1);
|
||||
e.checkcast(targetType);
|
||||
e.load_arg(0);
|
||||
e.checkcast(sourceType);
|
||||
}
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
PropertyDescriptor setter = setters[i];
|
||||
PropertyDescriptor getter = (PropertyDescriptor)names.get(setter.getName());
|
||||
if (getter != null) {
|
||||
MethodInfo read = ReflectUtils.getMethodInfo(getter.getReadMethod());
|
||||
MethodInfo write = ReflectUtils.getMethodInfo(setter.getWriteMethod());
|
||||
if (useConverter) {
|
||||
Type setterType = write.getSignature().getArgumentTypes()[0];
|
||||
e.load_local(targetLocal);
|
||||
e.load_arg(2);
|
||||
e.load_local(sourceLocal);
|
||||
e.invoke(read);
|
||||
e.box(read.getSignature().getReturnType());
|
||||
EmitUtils.load_class(e, setterType);
|
||||
e.push(write.getSignature().getName());
|
||||
e.invoke_interface(CONVERTER, CONVERT);
|
||||
e.unbox_or_zero(setterType);
|
||||
e.invoke(write);
|
||||
} else if (compatible(getter, setter)) {
|
||||
e.dup2();
|
||||
e.invoke(read);
|
||||
e.invoke(write);
|
||||
}
|
||||
}
|
||||
}
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
private static boolean compatible(PropertyDescriptor getter, PropertyDescriptor setter) {
|
||||
// TODO: allow automatic widening conversions?
|
||||
return setter.getPropertyType().isAssignableFrom(getter.getPropertyType());
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type);
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright 2003 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
|
||||
/**
|
||||
* @author Juozas Baliuka, Chris Nokleberg
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class BeanGenerator extends AbstractClassGenerator
|
||||
{
|
||||
private static final Source SOURCE = new Source(BeanGenerator.class.getName());
|
||||
private static final BeanGeneratorKey KEY_FACTORY =
|
||||
(BeanGeneratorKey)KeyFactory.create(BeanGeneratorKey.class);
|
||||
|
||||
interface BeanGeneratorKey {
|
||||
public Object newInstance(String superclass, Map props);
|
||||
}
|
||||
|
||||
private Class superclass;
|
||||
private Map props = new HashMap();
|
||||
private boolean classOnly;
|
||||
|
||||
public BeanGenerator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the class which the generated class will extend. The class
|
||||
* must not be declared as final, and must have a non-private
|
||||
* no-argument constructor.
|
||||
* @param superclass class to extend, or null to extend Object
|
||||
*/
|
||||
public void setSuperclass(Class superclass) {
|
||||
if (superclass != null && superclass.equals(Object.class)) {
|
||||
superclass = null;
|
||||
}
|
||||
this.superclass = superclass;
|
||||
// SPRING PATCH BEGIN
|
||||
setContextClass(superclass);
|
||||
// SPRING PATCH END
|
||||
}
|
||||
|
||||
public void addProperty(String name, Class type) {
|
||||
if (props.containsKey(name)) {
|
||||
throw new IllegalArgumentException("Duplicate property name \"" + name + "\"");
|
||||
}
|
||||
props.put(name, Type.getType(type));
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
if (superclass != null) {
|
||||
return superclass.getClassLoader();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(superclass);
|
||||
}
|
||||
|
||||
public Object create() {
|
||||
classOnly = false;
|
||||
return createHelper();
|
||||
}
|
||||
|
||||
public Object createClass() {
|
||||
classOnly = true;
|
||||
return createHelper();
|
||||
}
|
||||
|
||||
private Object createHelper() {
|
||||
if (superclass != null) {
|
||||
setNamePrefix(superclass.getName());
|
||||
}
|
||||
String superName = (superclass != null) ? superclass.getName() : "java.lang.Object";
|
||||
Object key = KEY_FACTORY.newInstance(superName, props);
|
||||
return super.create(key);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
int size = props.size();
|
||||
String[] names = (String[])props.keySet().toArray(new String[size]);
|
||||
Type[] types = new Type[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
types[i] = (Type)props.get(names[i]);
|
||||
}
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
ce.begin_class(Constants.V1_8,
|
||||
Constants.ACC_PUBLIC,
|
||||
getClassName(),
|
||||
superclass != null ? Type.getType(superclass) : Constants.TYPE_OBJECT,
|
||||
null,
|
||||
null);
|
||||
EmitUtils.null_constructor(ce);
|
||||
EmitUtils.add_properties(ce, names, types);
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
if (classOnly) {
|
||||
return type;
|
||||
} else {
|
||||
return ReflectUtils.newInstance(type);
|
||||
}
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
Class protoclass = (instance instanceof Class) ? (Class)instance : instance.getClass();
|
||||
if (classOnly) {
|
||||
return protoclass;
|
||||
} else {
|
||||
return ReflectUtils.newInstance(protoclass);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addProperties(BeanGenerator gen, Map props) {
|
||||
for (Iterator it = props.keySet().iterator(); it.hasNext();) {
|
||||
String name = (String)it.next();
|
||||
gen.addProperty(name, (Class)props.get(name));
|
||||
}
|
||||
}
|
||||
|
||||
public static void addProperties(BeanGenerator gen, Class type) {
|
||||
addProperties(gen, ReflectUtils.getBeanProperties(type));
|
||||
}
|
||||
|
||||
public static void addProperties(BeanGenerator gen, PropertyDescriptor[] descriptors) {
|
||||
for (int i = 0; i < descriptors.length; i++) {
|
||||
gen.addProperty(descriptors[i].getName(), descriptors[i].getPropertyType());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -97,7 +97,9 @@ abstract public class BeanMap implements Map {
|
|||
this.bean = bean;
|
||||
if (bean != null) {
|
||||
beanClass = bean.getClass();
|
||||
// SPRING PATCH BEGIN
|
||||
setContextClass(beanClass);
|
||||
// SPRING PATCH END
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright 2003,2004 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.beans.*;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Label;
|
||||
import org.springframework.asm.Type;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
class BeanMapEmitter extends ClassEmitter {
|
||||
private static final Type BEAN_MAP =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BeanMap");
|
||||
private static final Type FIXED_KEY_SET =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.FixedKeySet");
|
||||
private static final Signature CSTRUCT_OBJECT =
|
||||
TypeUtils.parseConstructor("Object");
|
||||
private static final Signature CSTRUCT_STRING_ARRAY =
|
||||
TypeUtils.parseConstructor("String[]");
|
||||
private static final Signature BEAN_MAP_GET =
|
||||
TypeUtils.parseSignature("Object get(Object, Object)");
|
||||
private static final Signature BEAN_MAP_PUT =
|
||||
TypeUtils.parseSignature("Object put(Object, Object, Object)");
|
||||
private static final Signature KEY_SET =
|
||||
TypeUtils.parseSignature("java.util.Set keySet()");
|
||||
private static final Signature NEW_INSTANCE =
|
||||
new Signature("newInstance", BEAN_MAP, new Type[]{ Constants.TYPE_OBJECT });
|
||||
private static final Signature GET_PROPERTY_TYPE =
|
||||
TypeUtils.parseSignature("Class getPropertyType(String)");
|
||||
|
||||
public BeanMapEmitter(ClassVisitor v, String className, Class type, int require) {
|
||||
super(v);
|
||||
|
||||
begin_class(Constants.V1_8, Constants.ACC_PUBLIC, className, BEAN_MAP, null, Constants.SOURCE_FILE);
|
||||
EmitUtils.null_constructor(this);
|
||||
EmitUtils.factory_method(this, NEW_INSTANCE);
|
||||
generateConstructor();
|
||||
|
||||
Map getters = makePropertyMap(ReflectUtils.getBeanGetters(type));
|
||||
Map setters = makePropertyMap(ReflectUtils.getBeanSetters(type));
|
||||
Map allProps = new HashMap();
|
||||
allProps.putAll(getters);
|
||||
allProps.putAll(setters);
|
||||
|
||||
if (require != 0) {
|
||||
for (Iterator it = allProps.keySet().iterator(); it.hasNext();) {
|
||||
String name = (String)it.next();
|
||||
if ((((require & BeanMap.REQUIRE_GETTER) != 0) && !getters.containsKey(name)) ||
|
||||
(((require & BeanMap.REQUIRE_SETTER) != 0) && !setters.containsKey(name))) {
|
||||
it.remove();
|
||||
getters.remove(name);
|
||||
setters.remove(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
generateGet(type, getters);
|
||||
generatePut(type, setters);
|
||||
|
||||
String[] allNames = getNames(allProps);
|
||||
generateKeySet(allNames);
|
||||
generateGetPropertyType(allProps, allNames);
|
||||
end_class();
|
||||
}
|
||||
|
||||
private Map makePropertyMap(PropertyDescriptor[] props) {
|
||||
Map names = new HashMap();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
names.put(props[i].getName(), props[i]);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
private String[] getNames(Map propertyMap) {
|
||||
return (String[])propertyMap.keySet().toArray(new String[propertyMap.size()]);
|
||||
}
|
||||
|
||||
private void generateConstructor() {
|
||||
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
|
||||
e.load_this();
|
||||
e.load_arg(0);
|
||||
e.super_invoke_constructor(CSTRUCT_OBJECT);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private void generateGet(Class type, final Map getters) {
|
||||
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_GET, null);
|
||||
e.load_arg(0);
|
||||
e.checkcast(Type.getType(type));
|
||||
e.load_arg(1);
|
||||
e.checkcast(Constants.TYPE_STRING);
|
||||
EmitUtils.string_switch(e, getNames(getters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
|
||||
public void processCase(Object key, Label end) {
|
||||
PropertyDescriptor pd = (PropertyDescriptor)getters.get(key);
|
||||
MethodInfo method = ReflectUtils.getMethodInfo(pd.getReadMethod());
|
||||
e.invoke(method);
|
||||
e.box(method.getSignature().getReturnType());
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
e.aconst_null();
|
||||
e.return_value();
|
||||
}
|
||||
});
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private void generatePut(Class type, final Map setters) {
|
||||
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, BEAN_MAP_PUT, null);
|
||||
e.load_arg(0);
|
||||
e.checkcast(Type.getType(type));
|
||||
e.load_arg(1);
|
||||
e.checkcast(Constants.TYPE_STRING);
|
||||
EmitUtils.string_switch(e, getNames(setters), Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
|
||||
public void processCase(Object key, Label end) {
|
||||
PropertyDescriptor pd = (PropertyDescriptor)setters.get(key);
|
||||
if (pd.getReadMethod() == null) {
|
||||
e.aconst_null();
|
||||
} else {
|
||||
MethodInfo read = ReflectUtils.getMethodInfo(pd.getReadMethod());
|
||||
e.dup();
|
||||
e.invoke(read);
|
||||
e.box(read.getSignature().getReturnType());
|
||||
}
|
||||
e.swap(); // move old value behind bean
|
||||
e.load_arg(2); // new value
|
||||
MethodInfo write = ReflectUtils.getMethodInfo(pd.getWriteMethod());
|
||||
e.unbox(write.getSignature().getArgumentTypes()[0]);
|
||||
e.invoke(write);
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
// fall-through
|
||||
}
|
||||
});
|
||||
e.aconst_null();
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private void generateKeySet(String[] allNames) {
|
||||
// static initializer
|
||||
declare_field(Constants.ACC_STATIC | Constants.ACC_PRIVATE, "keys", FIXED_KEY_SET, null);
|
||||
|
||||
CodeEmitter e = begin_static();
|
||||
e.new_instance(FIXED_KEY_SET);
|
||||
e.dup();
|
||||
EmitUtils.push_array(e, allNames);
|
||||
e.invoke_constructor(FIXED_KEY_SET, CSTRUCT_STRING_ARRAY);
|
||||
e.putfield("keys");
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
|
||||
// keySet
|
||||
e = begin_method(Constants.ACC_PUBLIC, KEY_SET, null);
|
||||
e.load_this();
|
||||
e.getfield("keys");
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private void generateGetPropertyType(final Map allProps, String[] allNames) {
|
||||
final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_TYPE, null);
|
||||
e.load_arg(0);
|
||||
EmitUtils.string_switch(e, allNames, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
|
||||
public void processCase(Object key, Label end) {
|
||||
PropertyDescriptor pd = (PropertyDescriptor)allProps.get(key);
|
||||
EmitUtils.load_class(e, Type.getType(pd.getPropertyType()));
|
||||
e.return_value();
|
||||
}
|
||||
public void processDefault() {
|
||||
e.aconst_null();
|
||||
e.return_value();
|
||||
}
|
||||
});
|
||||
e.end_method();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright 2003 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
|
||||
/**
|
||||
* @author Juozas Baliuka
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
abstract public class BulkBean
|
||||
{
|
||||
private static final BulkBeanKey KEY_FACTORY =
|
||||
(BulkBeanKey)KeyFactory.create(BulkBeanKey.class);
|
||||
|
||||
interface BulkBeanKey {
|
||||
public Object newInstance(String target, String[] getters, String[] setters, String[] types);
|
||||
}
|
||||
|
||||
protected Class target;
|
||||
protected String[] getters, setters;
|
||||
protected Class[] types;
|
||||
|
||||
protected BulkBean() { }
|
||||
|
||||
abstract public void getPropertyValues(Object bean, Object[] values);
|
||||
abstract public void setPropertyValues(Object bean, Object[] values);
|
||||
|
||||
public Object[] getPropertyValues(Object bean) {
|
||||
Object[] values = new Object[getters.length];
|
||||
getPropertyValues(bean, values);
|
||||
return values;
|
||||
}
|
||||
|
||||
public Class[] getPropertyTypes() {
|
||||
return types.clone();
|
||||
}
|
||||
|
||||
public String[] getGetters() {
|
||||
return getters.clone();
|
||||
}
|
||||
|
||||
public String[] getSetters() {
|
||||
return setters.clone();
|
||||
}
|
||||
|
||||
public static BulkBean create(Class target, String[] getters, String[] setters, Class[] types) {
|
||||
Generator gen = new Generator();
|
||||
gen.setTarget(target);
|
||||
gen.setGetters(getters);
|
||||
gen.setSetters(setters);
|
||||
gen.setTypes(types);
|
||||
return gen.create();
|
||||
}
|
||||
|
||||
public static class Generator extends AbstractClassGenerator {
|
||||
private static final Source SOURCE = new Source(BulkBean.class.getName());
|
||||
private Class target;
|
||||
private String[] getters;
|
||||
private String[] setters;
|
||||
private Class[] types;
|
||||
|
||||
public Generator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
|
||||
public void setTarget(Class target) {
|
||||
this.target = target;
|
||||
// SPRING PATCH BEGIN
|
||||
setContextClass(target);
|
||||
// SPRING PATCH END
|
||||
}
|
||||
|
||||
public void setGetters(String[] getters) {
|
||||
this.getters = getters;
|
||||
}
|
||||
|
||||
public void setSetters(String[] setters) {
|
||||
this.setters = setters;
|
||||
}
|
||||
|
||||
public void setTypes(Class[] types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return target.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(target);
|
||||
}
|
||||
|
||||
public BulkBean create() {
|
||||
setNamePrefix(target.getName());
|
||||
String targetClassName = target.getName();
|
||||
String[] typeClassNames = ReflectUtils.getNames(types);
|
||||
Object key = KEY_FACTORY.newInstance(targetClassName, getters, setters, typeClassNames);
|
||||
return (BulkBean)super.create(key);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) throws Exception {
|
||||
new BulkBeanEmitter(v, getClassName(), target, getters, setters, types);
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
BulkBean instance = (BulkBean)ReflectUtils.newInstance(type);
|
||||
instance.target = target;
|
||||
|
||||
int length = getters.length;
|
||||
instance.getters = new String[length];
|
||||
System.arraycopy(getters, 0, instance.getters, 0, length);
|
||||
|
||||
instance.setters = new String[length];
|
||||
System.arraycopy(setters, 0, instance.setters, 0, length);
|
||||
|
||||
instance.types = new Class[types.length];
|
||||
System.arraycopy(types, 0, instance.types, 0, types.length);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected Object nextInstance(Object instance) {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright 2003,2004 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
class BulkBeanEmitter extends ClassEmitter {
|
||||
private static final Signature GET_PROPERTY_VALUES =
|
||||
TypeUtils.parseSignature("void getPropertyValues(Object, Object[])");
|
||||
private static final Signature SET_PROPERTY_VALUES =
|
||||
TypeUtils.parseSignature("void setPropertyValues(Object, Object[])");
|
||||
private static final Signature CSTRUCT_EXCEPTION =
|
||||
TypeUtils.parseConstructor("Throwable, int");
|
||||
private static final Type BULK_BEAN =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BulkBean");
|
||||
private static final Type BULK_BEAN_EXCEPTION =
|
||||
TypeUtils.parseType("org.springframework.cglib.beans.BulkBeanException");
|
||||
|
||||
public BulkBeanEmitter(ClassVisitor v,
|
||||
String className,
|
||||
Class target,
|
||||
String[] getterNames,
|
||||
String[] setterNames,
|
||||
Class[] types) {
|
||||
super(v);
|
||||
|
||||
Method[] getters = new Method[getterNames.length];
|
||||
Method[] setters = new Method[setterNames.length];
|
||||
validate(target, getterNames, setterNames, types, getters, setters);
|
||||
|
||||
begin_class(Constants.V1_8, Constants.ACC_PUBLIC, className, BULK_BEAN, null, Constants.SOURCE_FILE);
|
||||
EmitUtils.null_constructor(this);
|
||||
generateGet(target, getters);
|
||||
generateSet(target, setters);
|
||||
end_class();
|
||||
}
|
||||
|
||||
private void generateGet(final Class target, final Method[] getters) {
|
||||
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, GET_PROPERTY_VALUES, null);
|
||||
if (getters.length > 0) {
|
||||
e.load_arg(0);
|
||||
e.checkcast(Type.getType(target));
|
||||
Local bean = e.make_local();
|
||||
e.store_local(bean);
|
||||
for (int i = 0; i < getters.length; i++) {
|
||||
if (getters[i] != null) {
|
||||
MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
|
||||
e.load_arg(1);
|
||||
e.push(i);
|
||||
e.load_local(bean);
|
||||
e.invoke(getter);
|
||||
e.box(getter.getSignature().getReturnType());
|
||||
e.aastore();
|
||||
}
|
||||
}
|
||||
}
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private void generateSet(final Class target, final Method[] setters) {
|
||||
// setPropertyValues
|
||||
CodeEmitter e = begin_method(Constants.ACC_PUBLIC, SET_PROPERTY_VALUES, null);
|
||||
if (setters.length > 0) {
|
||||
Local index = e.make_local(Type.INT_TYPE);
|
||||
e.push(0);
|
||||
e.store_local(index);
|
||||
e.load_arg(0);
|
||||
e.checkcast(Type.getType(target));
|
||||
e.load_arg(1);
|
||||
Block handler = e.begin_block();
|
||||
int lastIndex = 0;
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
if (setters[i] != null) {
|
||||
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
|
||||
int diff = i - lastIndex;
|
||||
if (diff > 0) {
|
||||
e.iinc(index, diff);
|
||||
lastIndex = i;
|
||||
}
|
||||
e.dup2();
|
||||
e.aaload(i);
|
||||
e.unbox(setter.getSignature().getArgumentTypes()[0]);
|
||||
e.invoke(setter);
|
||||
}
|
||||
}
|
||||
handler.end();
|
||||
e.return_value();
|
||||
e.catch_exception(handler, Constants.TYPE_THROWABLE);
|
||||
e.new_instance(BULK_BEAN_EXCEPTION);
|
||||
e.dup_x1();
|
||||
e.swap();
|
||||
e.load_local(index);
|
||||
e.invoke_constructor(BULK_BEAN_EXCEPTION, CSTRUCT_EXCEPTION);
|
||||
e.athrow();
|
||||
} else {
|
||||
e.return_value();
|
||||
}
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
private static void validate(Class target,
|
||||
String[] getters,
|
||||
String[] setters,
|
||||
Class[] types,
|
||||
Method[] getters_out,
|
||||
Method[] setters_out) {
|
||||
int i = -1;
|
||||
if (setters.length != types.length || getters.length != types.length) {
|
||||
throw new BulkBeanException("accessor array length must be equal type array length", i);
|
||||
}
|
||||
try {
|
||||
for (i = 0; i < types.length; i++) {
|
||||
if (getters[i] != null) {
|
||||
Method method = ReflectUtils.findDeclaredMethod(target, getters[i], null);
|
||||
if (method.getReturnType() != types[i]) {
|
||||
throw new BulkBeanException("Specified type " + types[i] +
|
||||
" does not match declared type " + method.getReturnType(), i);
|
||||
}
|
||||
if (Modifier.isPrivate(method.getModifiers())) {
|
||||
throw new BulkBeanException("Property is private", i);
|
||||
}
|
||||
getters_out[i] = method;
|
||||
}
|
||||
if (setters[i] != null) {
|
||||
Method method = ReflectUtils.findDeclaredMethod(target, setters[i], new Class[]{ types[i] });
|
||||
if (Modifier.isPrivate(method.getModifiers()) ){
|
||||
throw new BulkBeanException("Property is private", i);
|
||||
}
|
||||
setters_out[i] = method;
|
||||
}
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new BulkBeanException("Cannot find specified property", i);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2003 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import org.springframework.cglib.core.CodeGenerationException;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked", "serial"})
|
||||
public class BulkBeanException extends RuntimeException
|
||||
{
|
||||
private int index;
|
||||
private Throwable cause;
|
||||
|
||||
public BulkBeanException(String message, int index) {
|
||||
super(message);
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public BulkBeanException(Throwable cause, int index) {
|
||||
super(cause.getMessage());
|
||||
this.index = index;
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2003 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public /* need it for class loading */ class FixedKeySet extends AbstractSet {
|
||||
private Set set;
|
||||
private int size;
|
||||
|
||||
public FixedKeySet(String[] keys) {
|
||||
size = keys.length;
|
||||
set = Collections.unmodifiableSet(new HashSet(Arrays.asList(keys)));
|
||||
}
|
||||
|
||||
public Iterator iterator() {
|
||||
return set.iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2003,2004 The Apache Software Foundation
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* https://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.beans;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.ProtectionDomain;
|
||||
import org.springframework.cglib.core.*;
|
||||
import org.springframework.asm.ClassVisitor;
|
||||
import org.springframework.asm.Type;
|
||||
/**
|
||||
* @author Chris Nokleberg
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public class ImmutableBean
|
||||
{
|
||||
private static final Type ILLEGAL_STATE_EXCEPTION =
|
||||
TypeUtils.parseType("IllegalStateException");
|
||||
private static final Signature CSTRUCT_OBJECT =
|
||||
TypeUtils.parseConstructor("Object");
|
||||
private static final Class[] OBJECT_CLASSES = { Object.class };
|
||||
private static final String FIELD_NAME = "CGLIB$RWBean";
|
||||
|
||||
private ImmutableBean() {
|
||||
}
|
||||
|
||||
public static Object create(Object bean) {
|
||||
Generator gen = new Generator();
|
||||
gen.setBean(bean);
|
||||
return gen.create();
|
||||
}
|
||||
|
||||
public static class Generator extends AbstractClassGenerator {
|
||||
private static final Source SOURCE = new Source(ImmutableBean.class.getName());
|
||||
private Object bean;
|
||||
private Class target;
|
||||
|
||||
public Generator() {
|
||||
super(SOURCE);
|
||||
}
|
||||
|
||||
public void setBean(Object bean) {
|
||||
this.bean = bean;
|
||||
target = bean.getClass();
|
||||
// SPRING PATCH BEGIN
|
||||
setContextClass(target);
|
||||
// SPRING PATCH END
|
||||
}
|
||||
|
||||
protected ClassLoader getDefaultClassLoader() {
|
||||
return target.getClassLoader();
|
||||
}
|
||||
|
||||
protected ProtectionDomain getProtectionDomain() {
|
||||
return ReflectUtils.getProtectionDomain(target);
|
||||
}
|
||||
|
||||
public Object create() {
|
||||
String name = target.getName();
|
||||
setNamePrefix(name);
|
||||
return super.create(name);
|
||||
}
|
||||
|
||||
public void generateClass(ClassVisitor v) {
|
||||
Type targetType = Type.getType(target);
|
||||
ClassEmitter ce = new ClassEmitter(v);
|
||||
ce.begin_class(Constants.V1_8,
|
||||
Constants.ACC_PUBLIC,
|
||||
getClassName(),
|
||||
targetType,
|
||||
null,
|
||||
Constants.SOURCE_FILE);
|
||||
|
||||
ce.declare_field(Constants.ACC_FINAL | Constants.ACC_PRIVATE, FIELD_NAME, targetType, null);
|
||||
|
||||
CodeEmitter e = ce.begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT, null);
|
||||
e.load_this();
|
||||
e.super_invoke_constructor();
|
||||
e.load_this();
|
||||
e.load_arg(0);
|
||||
e.checkcast(targetType);
|
||||
e.putfield(FIELD_NAME);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
|
||||
PropertyDescriptor[] descriptors = ReflectUtils.getBeanProperties(target);
|
||||
Method[] getters = ReflectUtils.getPropertyMethods(descriptors, true, false);
|
||||
Method[] setters = ReflectUtils.getPropertyMethods(descriptors, false, true);
|
||||
|
||||
for (int i = 0; i < getters.length; i++) {
|
||||
MethodInfo getter = ReflectUtils.getMethodInfo(getters[i]);
|
||||
e = EmitUtils.begin_method(ce, getter, Constants.ACC_PUBLIC);
|
||||
e.load_this();
|
||||
e.getfield(FIELD_NAME);
|
||||
e.invoke(getter);
|
||||
e.return_value();
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
for (int i = 0; i < setters.length; i++) {
|
||||
MethodInfo setter = ReflectUtils.getMethodInfo(setters[i]);
|
||||
e = EmitUtils.begin_method(ce, setter, Constants.ACC_PUBLIC);
|
||||
e.throw_exception(ILLEGAL_STATE_EXCEPTION, "Bean is immutable");
|
||||
e.end_method();
|
||||
}
|
||||
|
||||
ce.end_class();
|
||||
}
|
||||
|
||||
protected Object firstInstance(Class type) {
|
||||
return ReflectUtils.newInstance(type, OBJECT_CLASSES, new Object[]{ bean });
|
||||
}
|
||||
|
||||
// TODO: optimize
|
||||
protected Object nextInstance(Object instance) {
|
||||
return firstInstance(instance.getClass());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Spring's repackaging of the
|
||||
* <a href="http://cglib.sourceforge.net">CGLIB</a> beans package
|
||||
* <a href="https://github.com/cglib/cglib">CGLIB</a> beans package
|
||||
* (for internal use only).
|
||||
*
|
||||
* <p>As this repackaging happens at the class file level, sources
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Spring's repackaging of the
|
||||
* <a href="http://cglib.sourceforge.net">CGLIB</a> core package
|
||||
* <a href="https://github.com/cglib/cglib">CGLIB</a> core package
|
||||
* (for internal use only).
|
||||
*
|
||||
* <p>As this repackaging happens at the class file level, sources
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**
|
||||
* Spring's repackaging of the
|
||||
* <a href="http://cglib.sourceforge.net">CGLIB</a> proxy package
|
||||
* <a href="https://github.com/cglib/cglib">CGLIB</a> proxy package
|
||||
* (for internal use only).
|
||||
*
|
||||
* <p>As this repackaging happens at the class file level, sources
|
||||
|
|
|
@ -62,6 +62,18 @@ public class UrlResource extends AbstractFileResolvingResource {
|
|||
private volatile URL cleanedUrl;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code UrlResource} based on the given URL object.
|
||||
* @param url a URL
|
||||
* @see #UrlResource(URI)
|
||||
* @see #UrlResource(String)
|
||||
*/
|
||||
public UrlResource(URL url) {
|
||||
Assert.notNull(url, "URL must not be null");
|
||||
this.uri = null;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code UrlResource} based on the given URI object.
|
||||
* @param uri a URI
|
||||
|
@ -74,16 +86,6 @@ public class UrlResource extends AbstractFileResolvingResource {
|
|||
this.url = uri.toURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code UrlResource} based on the given URL object.
|
||||
* @param url a URL
|
||||
*/
|
||||
public UrlResource(URL url) {
|
||||
Assert.notNull(url, "URL must not be null");
|
||||
this.uri = null;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code UrlResource} based on a URL path.
|
||||
* <p>Note: The given path needs to be pre-encoded if necessary.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
||||
|
@ -49,8 +49,8 @@ import org.springframework.util.ClassUtils;
|
|||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link SingleConnectionFactory} subclass that adds {@link jakarta.jms.Session}
|
||||
* caching as well {@link jakarta.jms.MessageProducer} caching. This ConnectionFactory
|
||||
* {@link SingleConnectionFactory} subclass that adds {@link Session} caching as well as
|
||||
* {@link MessageProducer} and {@link MessageConsumer} caching. This ConnectionFactory
|
||||
* also switches the {@link #setReconnectOnException "reconnectOnException" property}
|
||||
* to "true" by default, allowing for automatic recovery of the underlying Connection.
|
||||
*
|
||||
|
@ -82,8 +82,19 @@ import org.springframework.util.ObjectUtils;
|
|||
* Re-registering a durable consumer for the same subscription on the same
|
||||
* Session handle is not supported; close and reobtain a cached Session first.
|
||||
*
|
||||
* <p>Last but not least, MessageProducers and MessageConsumers for temporary
|
||||
* queues and topics (TemporaryQueue/TemporaryTopic) will never be cached.
|
||||
* Unfortunately, WebLogic JMS happens to implement the temporary queue/topic
|
||||
* interfaces on its regular destination implementation, mis-indicating that
|
||||
* none of its destinations can be cached. Please use a different connection
|
||||
* pool/cache on WebLogic, or customize this class for WebLogic purposes.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 2.5.3
|
||||
* @see Connection
|
||||
* @see Session
|
||||
* @see MessageProducer
|
||||
* @see MessageConsumer
|
||||
*/
|
||||
public class CachingConnectionFactory extends SingleConnectionFactory {
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* Copyright 2002-2022 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.
|
|
@ -672,17 +672,26 @@ takes a reference to a standard `ConnectionFactory` that would typically come fr
|
|||
===== Using `CachingConnectionFactory`
|
||||
|
||||
The `CachingConnectionFactory` extends the functionality of `SingleConnectionFactory`
|
||||
and adds the caching of `Session`, `MessageProducer`, and `MessageConsumer` instances. The initial
|
||||
cache size is set to `1`. You can use the `sessionCacheSize` property to increase the number of
|
||||
cached sessions. Note that the number of actual cached sessions is more than that
|
||||
number, as sessions are cached based on their acknowledgment mode, so there can be up to
|
||||
four cached session instances (one for each
|
||||
acknowledgment mode) when `sessionCacheSize` is set to one. `MessageProducer` and `MessageConsumer` instances are cached within their
|
||||
owning session and also take into account the unique properties of the producers and
|
||||
consumers when caching. MessageProducers are cached based on their destination.
|
||||
MessageConsumers are cached based on a key composed of the destination, selector,
|
||||
and adds the caching of `Session`, `MessageProducer`, and `MessageConsumer` instances.
|
||||
The initial cache size is set to `1`. You can use the `sessionCacheSize` property to
|
||||
increase the number of cached sessions. Note that the number of actual cached sessions
|
||||
is more than that number, as sessions are cached based on their acknowledgment mode,
|
||||
so there can be up to four cached session instances (one for each acknowledgment mode)
|
||||
when `sessionCacheSize` is set to one. `MessageProducer` and `MessageConsumer` instances
|
||||
are cached within their owning session and also take into account the unique properties
|
||||
of the producers and consumers when caching. MessageProducers are cached based on their
|
||||
destination. MessageConsumers are cached based on a key composed of the destination, selector,
|
||||
noLocal delivery flag, and the durable subscription name (if creating durable consumers).
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
MessageProducers and MessageConsumers for temporary queues and topics
|
||||
(TemporaryQueue/TemporaryTopic) will never be cached. Unfortunately, WebLogic JMS happens
|
||||
to implement the temporary queue/topic interfaces on its regular destination implementation,
|
||||
mis-indicating that none of its destinations can be cached. Please use a different connection
|
||||
pool/cache on WebLogic, or customize `CachingConnectionFactory` for WebLogic purposes.
|
||||
====
|
||||
|
||||
|
||||
[[jms-destinations]]
|
||||
==== Destination Management
|
||||
|
|
Loading…
Reference in New Issue