标签:
实例代码: public class EmployeeAction extends ActionSupport implements Preparable,ModelDriven<Employee>{ 1. params拦截器首先给action中的相关参数赋值,如id private int id; private EmployeeService employeeService; public void setEmployeeService(EmployeeService employeeService) { this.employeeService = employeeService; } //所以当触发save action方法时会在Preparable的拦截器中自动查找action中是否包含 prepareSave()或prepareDoSave() 方法如果包含这个方法就先执行prepareSave() prepareDoSave() public String save() { System. out.println(employee ); employeeService.save(employee ); return "save-success" ; } //通过观察源码执行过程得知 // PrepareInterceptor 拦截器将调用 prepare() 方法,prepareActionMethodName()方法 或 prepareDoActionMethodName ()方法 private Employee employee; public void prepareSave(){ //所以在这里进行初始化Model的类 employee= new Employee(); } @Override public Employee getModel() { return employee ; } // 若 Action 实现 Preparable 接口,则 Action 方法需实现 prepare() 方法 //2. prepare拦截器执行prepare方法,prepare方法中会根据参数,如id,去调用业务逻辑,设置model对象 但是一般这个方法都不进行执行具体的方法内容 //PrepareInterceptor 拦截器会根据 alwaysInvokePrepare 属性决定是否执行prepare()方法 @Override public void prepare() throws Exception {} } 源码实现: public class PrepareInterceptor extends MethodFilterInterceptor { PrepareInterceptor 拦截器根据 firstCallPrepareDo 属性决定获取 prepareActionMethodName 、 prepareDoActionMethodName的顺序。默认情况下先获取 prepareActionMethodName (), 如果没有该方法,就寻找prepareDoActionMethodName()。 如果找到对应的方法就调用该方法 private final static String PREPARE_PREFIX = "prepare"; private final static String ALT_PREPARE_PREFIX = "prepareDo"; // 拦截器会根据 alwaysInvokePrepare 属性决定是否执行prepare()方法 private boolean alwaysInvokePrepare = true; private boolean firstCallPrepareDo = false; public void setAlwaysInvokePrepare(String alwaysInvokePrepare) { this.alwaysInvokePrepare = Boolean.parseBoolean(alwaysInvokePrepare); } public void setFirstCallPrepareDo(String firstCallPrepareDo) { this.firstCallPrepareDo = Boolean.parseBoolean(firstCallPrepareDo); } @Override public String doIntercept(ActionInvocation invocation) throws Exception { Object action = invocation.getAction(); if (action instanceof Preparable) { try { String[] prefixes; // firstCallPrepareDo = false; if (firstCallPrepareDo ) { prefixes = new String[] {ALT_PREPARE_PREFIX , PREPARE_PREFIX}; } else { prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX }; } //会先执行prefixes 数组在PrefixMethodInvocationUtil的invokePrefixMethod 方法中 PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes); } catch (InvocationTargetException e) { throw e; } //拦截器会根据 alwaysInvokePrepare 属性决定是否执行prepare()方法 if (alwaysInvokePrepare ) { ((Preparable) action).prepare(); } } return invocation.invoke(); } //执行prefixes 数组在PrefixMethodInvocationUtil类中 默认执行方法 private static final String DEFAULT_INVOCATION_METHODNAME = "execute"; public static void invokePrefixMethod(ActionInvocation actionInvocation, String[] prefixes) { //得到请求的action类对象 Object action = actionInvocation. getAction(); //得到请求的action类对象请求的方法名 String methodName = actionInvocation.getProxy().getMethod(); //如果方法名称为NUll就赋值默认的execute方法 if (methodName == null) { methodName = DEFAULT_INVOCATION_METHODNAME; } //得到前缀方法 也就是prepareSave()或prepareDoSave() 方法如果包含这个方法就先执 行prepareSave()prepareDoSave() 也就是在请求方action的方法加上prepareActionMethodName()方法 或 prepareDoActionMethodName ()方法 通过getPrefixedMethod 这个方法进行的装配 Method method = getPrefixedMethod (prefixes, methodName, action); //如果包含prepareSave()或prepareDoSave() 方法如果包含这个方法就先执 行prepareSave()prepareDoSave()就进行调用这个对应的方法 if (method != null) { 这里调用 method.invoke(action, new Object[0]); } } public static Method getPrefixedMethod (String[] prefixes, String methodName, Object action) { assert(prefixes != null); String capitalizedMethodName = capitalizeMethodName(methodName); for (String prefixe : prefixes) { //在这里进行配置成 prepareActionMethodName()方法 或 prepareDoActionMethodName String prefixedMethodName = prefixe + capitalizedMethodName; try { return action.getClass().getMethod(prefixedMethodName, EMPTY_CLASS_ARRAY); } catch (NoSuchMethodException e) { } } } return null ; } 以上就是ModelDriven 和 Preparable 拦截器的使用和源码的原理 个人感觉写的比较繁琐了
标签:
原文地址:http://www.cnblogs.com/lflx/p/4398195.html