I've implemented a little solution to inject SpringBean of Wicket Pages on
the un-serialization event :
1 - Make the SpringContext available in a static way :
public class MyWebApplication extends SpringWebApplication {
private static ApplicationContext springApplicationContext = null ;
@Override
protected void init() {
super.init();
addComponentInstantiationListener(new
SpringComponentInjector(this));
springApplicationContext =
getSpringContextLocator().getSpringContext()
;
(...)
public static ApplicationContext getApplicationContext(){
return springApplicationContext ;
}
(...)
}
2 - Define an Helper to inspect by introspection your classes in order to :
select all transiant fields having a SpringBean and a Required annotation
make access to the setter method of the fields (throw all super classes
of it)
public class AnnotatedFieldHelper{
private Class clazz ;
private Field field = null;
private boolean isTransient = false;
private boolean isSpringBean = false;
private boolean isRequired = false;
private String springBeanName = null;
(...)
/**
* Build a list of all transient field of the Class
* @param clazz
* @return
*/
public static List<AnnotatedField> getTransientAnnotatedField(Class
clazz)
{
List<AnnotatedField> list = new ArrayList<AnnotatedField>();
List<Field> fields = new ArrayList<Field>() ;
// Get all fields (event field from the super classes )
Class cl = clazz ;
do{
for (Field f : cl.getDeclaredFields()){
fields.add(f) ;
}
cl = cl.getSuperclass() ;
}while ( cl != null ) ;
for (Field f : fields) {
if (Modifier.isTransient(f.getModifiers())) {
AnnotatedField af = new AnnotatedField(clazz,
f);
af.setTransient(true);
Annotation[] annotations = f.getAnnotations();
for (Annotation a : annotations) {
if (a instanceof SpringBean) {
af.setSpringBean(true);
SpringBean sb = (SpringBean) a;
String patternStr =
"@org.apache.wicket.spring.injection.annot.SpringBean\\(name=(.*)\\)";
Pattern pattern =
Pattern.compile(patternStr);
Matcher matcher =
pattern.matcher("");
matcher.reset(sb.toString());
if (matcher.find()) {
af.setSpringBeanName(matcher.group(1));
}else{
af.setSpringBeanName(null);
}
}
}
String setterName = getSetterName (f.getName());
boolean isRequired = false;
try {
Method setter =
clazz.getMethod(setterName, f.getType());
Annotation[] annotationsSetter =
setter.getAnnotations();
for (Annotation a : annotationsSetter) {
if (a instanceof Required) {
isRequired = true;
}
}
} catch (NoSuchMethodException e) {
isRequired = false;
} catch (SecurityException e) {
isRequired = false;
}
af.setRequired(isRequired);
list.add(af);
}
}
return list;
}
}
3 - Define a super class for all your Wicket Page to serialize all transiant
SpringBean
public class MySuperPage extends WebPage {
@Override
public ApplicationContext getApplicationContext(){
return MyWebApplication.getApplicationContext() ;
}
/**
* Set all transient fields of the page managed by Spring from the
spring
* context
*
* @throws RuntimeException
*/
protected void setAllTransientSpringFields() throws RuntimeException {
List<AnnotatedField> tafList =
AnnotatedFieldHelper.getTransientAnnotatedField(getClass());
for (AnnotatedField af : tafList) {
if (af.isSpringBean() && af.getSpringBeanName() !=
null) {
try {
Object bean =
getApplicationContext().getBean(af.getSpringBeanName());
af.getSetter().invoke(this, bean);
} catch (BeansException e) {
throw new RuntimeException("Impossible
to get " +
af.getSpringBeanName()
+ " the from the Spring
Context");
} catch (Exception e) {
throw new RuntimeException("Impossible
to set " +
af.getField().getName());
}
}
}
}
4 - Put transiant all SpringBean not serializable of the Wicket Page and
define the readObject method using your helper
public class MyPage extends MySuperPage {
private static final long serialVersionUID = 1L;
@SpringBean(name = "mySpringBean")
transient MyPOJO config;
@Required
public void setMyPOJO(MyPOJO config) {
this.config = config;
}
(...)
/**
* Creates transient objects
* Annotation introspection for all Required transient field
*/
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
stream.defaultReadObject();
setAllTransientSpringFields();
}
-----------------------------------------------------------------------------
Some questions ?
- Is it a good way do that ?
- Is there an existing helper to do that ?
- If it's a good way and if ther is no existing helper, can i contrib to
Wicket ?
Regards,
Gerald Reinhart
--
View this message in context:
http://www.nabble.com/%40SpringBean-and-serialization-tp15330505p18691954.html
Sent from the Wicket - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]