1.web层(action)
StrutsAction类:
java 代码
- public class StrutsAction extends DispatchAction
继承了分发Action类,在StrutsAction里还做了几个重要处理
A:设置Struts 中数字<->字符串转换
B:Object和Form之间的copyProperties
C:Save出错的Message
StrutsEntityAction类:这个类是供具体的实体Action来继承的
java 代码
- public abstract class StrutsEntityAction < T, M extends EntityDao < T > >
- extends StrutsAction implements InitializingBean
因为implements了InitializingBean类,所以需要实现方法:afterPropertiesSet
java 代码
- /**
- * Init回调函数,初始化一系列泛型参数.
- */
- public void afterPropertiesSet() {
- // 根据T,反射获得entityClass
- entityClass = GenericsUtils.getSuperClassGenricType(getClass());
- // 根据M,反射获得符合M类型的manager
- List < Field > fields = BeanUtils.getFieldsByType(this, GenericsUtils.getSuperClassGenricType(getClass(), 1));
- Assert.isTrue(fields.size() == 1, "subclass's has not only one entity manager property.");
- try {
- entityManager = (M) BeanUtils.forceGetProperty(this, fields.get(0).getName());
- Assert.notNull(entityManager, "subclass not inject manager to action sucessful.");
- } catch (Exception e) {
- ReflectionUtils.handleReflectionException(e);
- }
- // 反射获得entity的主键类型
- try {
- idName = entityManager.getIdName(entityClass);
- idClass = BeanUtils.getPropertyType(entityClass, idName);
- } catch (Exception e) {
- ReflectionUtils.handleReflectionException(e);
- }
- }
具体看下上面这段代码:
java 代码
- entityClass = GenericsUtils.getSuperClassGenricType(getClass());
这个和HibernateEntityDao里根据T,运用反射获得实际绑定entityClass(实体类)是一样的。
java 代码
- List < Field > fields = BeanUtils.getFieldsByType(this, GenericsUtils.getSuperClassGenricType(getClass(), 1));
这句代码里GenericsUtils.getSuperClassGenricType(getClass(), 1)获得实体Action传递过来的第2个泛型参数.比如:UserManager.class
然后又调用BeanUtils里的getFieldsByType方法。该方法具体为:
java 代码
- /**
- * 按Filed变量的类型取得Field变量列表.
- */
- public static List< Field > getFieldsByType(Object object, Class type) {
- List< Field > list = new ArrayList< Field >();
- Field[] fields = object.getClass().getDeclaredFields();
- for (Field field : fields) {
- System.out.println(field.getType() + ":" + field.getName());
- if (field.getType().isAssignableFrom(type)) {
- list.add(field);
- }
- }
- return list;
- }
这段代码也就是根据传递进来的Class类型,获得用该类型定义的变量的列表List,也就是在具体的某个实体Action里,用该实体Manager定义的具体实例变量的一个List,比如:UserAction里用UserManager定义的实例变量的列表
继续看StrutsEntityAction里的afterPropertiesSet方法
java 代码
- entityManager = ( M ) BeanUtils.forceGetProperty(this, fields.get(0).getName());
java 代码
- /**
- * 暴力获取对象变量值,忽略private,protected修饰符的限制.
- *
- * @throws NoSuchFieldException 如果没有该Field时抛出.
- */
- public static Object forceGetProperty(Object object, String propertyName) throws NoSuchFieldException {
- Assert.notNull(object);
- Assert.hasText(propertyName);
- Field field = getDeclaredField(object, propertyName);
- boolean accessible = field.isAccessible();
- field.setAccessible(true);
- Object result = null;
- try {
- result = field.get(object);
- } catch (IllegalAccessException e) {
- logger.info("error wont' happen");
- }
- field.setAccessible(accessible);
- return result;
- }