Java Spring aop,cglib增强类丢失通用信息
我有一个struts 2 action类:Java Spring aop,cglib增强类丢失通用信息,java,json,spring,struts2,cglib,Java,Json,Spring,Struts2,Cglib,我有一个struts 2 action类: public class MyAction{ private ArrayList<User> users; public void setUsers(ArrayList<User> users){ this.users = users; } public String doMyAction(){ //... } } 在这一行: Type[] generic
public class MyAction{
private ArrayList<User> users;
public void setUsers(ArrayList<User> users){
this.users = users;
}
public String doMyAction(){
//...
}
}
在这一行:
Type[] genericTypes = method.getGenericParameterTypes();
启用AOP时,它会根据users
字段的setter方法返回java.util.ArrayList
。但是java.util.ArrayList
当cglib代理时,我的action类似乎丢失了它的通用信息。我也发现了这个
我可以从aop配置中排除我的方法来解决这个问题。但我仍然想知道是否有更好的解决方案?Cglib是在泛型类型存在之前创建的。代理作为cglib中代理类的子类生成,该类不保留泛型类型信息。因此,您无法从proxy类查询它。我的想法是尝试查找代理背后的实际类型。根据spring文档,从SpringAOP获得的任何代理都实现了
org.springframework.aop.framework.Advised
接口,该接口公开了查询目标类的方法
Any AOP proxy obtained from Spring can be cast to this interface to allow manipulation of its AOP advice.
因此这里我们有一个相当大的选择,我们可以下载struts json插件源代码并构建我们自己的源代码,修改JSONPopulator的populateObject
方法
public void populateObject(Object object, final Map elements) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException, IntrospectionException,
IllegalArgumentException, JSONException, InstantiationException {
Class clazz = object.getClass();
// if it is a proxy, find the actual type behind it
if(Advised.class.isAssignableFrom(clazz)){
clazz = ((Advised)object).getTargetSource().getTargetClass();
}
BeanInfo info = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] props = info.getPropertyDescriptors();
// iterate over class fields
for (int i = 0; i < props.length; ++i) {
PropertyDescriptor prop = props[i];
String name = prop.getName();
if (elements.containsKey(name)) {
Object value = elements.get(name);
Method method = prop.getWriteMethod();
if (method != null) {
JSON json = method.getAnnotation(JSON.class);
if ((json != null) && !json.deserialize()) {
continue;
}
// use only public setters
if (Modifier.isPublic(method.getModifiers())) {
Class[] paramTypes = method.getParameterTypes();
Type[] genericTypes = method.getGenericParameterTypes();
if (paramTypes.length == 1) {
Object convertedValue = this.convert(paramTypes[0], genericTypes[0], value,
method);
method.invoke(object, new Object[] { convertedValue });
}
}
}
}
}
}
public void populateObject(Object object, final Map elements) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException, IntrospectionException,
IllegalArgumentException, JSONException, InstantiationException {
Class clazz = object.getClass();
// if it is a proxy, find the actual type behind it
if(Advised.class.isAssignableFrom(clazz)){
clazz = ((Advised)object).getTargetSource().getTargetClass();
}
BeanInfo info = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] props = info.getPropertyDescriptors();
// iterate over class fields
for (int i = 0; i < props.length; ++i) {
PropertyDescriptor prop = props[i];
String name = prop.getName();
if (elements.containsKey(name)) {
Object value = elements.get(name);
Method method = prop.getWriteMethod();
if (method != null) {
JSON json = method.getAnnotation(JSON.class);
if ((json != null) && !json.deserialize()) {
continue;
}
// use only public setters
if (Modifier.isPublic(method.getModifiers())) {
Class[] paramTypes = method.getParameterTypes();
Type[] genericTypes = method.getGenericParameterTypes();
if (paramTypes.length == 1) {
Object convertedValue = this.convert(paramTypes[0], genericTypes[0], value,
method);
method.invoke(object, new Object[] { convertedValue });
}
}
}
}
}
}
// if it is a proxy, find the actual type behind it
if(Advised.class.isAssignableFrom(clazz)){
clazz = ((Advised)object).getTargetSource().getTargetClass();
}