Struts2框架中有很多值得学习的地方,本文讲述Aware接口的使用。

在Struts2和Spring框架中,为了在运行时获得某个对象,可以采用实现某个Aware接口的方式来获得。


例如,使用ServletRequestAware、ServletResponseAware等Aware 接口与外部环境交互。

 

public class ServletConfigInterceptor extends AbstractInterceptor implements StrutsStatics {

 

  private static final long serialVersionUID = 605261777858676638L;

 

  
 
  public String intercept(ActionInvocation invocation) throws Exception {
 
   final Object action = invocation.getAction();
 
   final ActionContext context = invocation.getInvocationContext();
 

   /**
 
    * 8个可能实现的接口,8个if,而不是if else,因为可能需要同时接收8个参数
 
    */
 
   if (action instanceof ServletRequestAware) {
 
    HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);
 
    ((ServletRequestAware) action).setServletRequest(request);
 
   }
 

  

 

   if (action instanceof ServletResponseAware) {
 
    HttpServletResponse response = (HttpServletResponse) context.get(HTTP_RESPONSE);
 
    ((ServletResponseAware) action).setServletResponse(response);
 
   }
 

   //省略了很多代码
 
   return invocation.invoke();
 
  }
 
 }

  逐次扫描Action是否实现了某个Aware接口,然后将Action强制转化成这个Aware接口并调用其方法完成交互对象的设置。实际上,ServletConfigInterceptor 这个拦截器为我们打造了一个对Action进行扩展的范例。


 


这个范例的打造分为三个过程:


  1.定义一个接口;


  2.让Action实现接口;


  3.在拦截器中将Action强制转化为接口,完成接口方法的调用逻辑。


 


  这三个过程的代码逻辑调用蕴含了两种不同的Action扩展结果:
其一,通过Action实现的接口,向Action传递外部信息;


其二,通过Action实现的接口,完成功能扩展。这里所采用的交互方式,其主要依据实际上是面向对象概念中类与接口之间的关系。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
  如果,我们将Action和拦截器换成自己代码中的定义或实现,就可以获得这种设计方法所带来的好处。
 下面是模仿ServletConfigInterceptor 改编而来的例子。


 


package org.leiwen.struts2.aware;

 

 public interface Application {

 

  String getName();
 
 }
 

  

 

 package org.leiwen.struts2.aware;

 

 //ApplicationAware接口
 
 public interface ApplicationAware {
 

  void setApplication(Application app);
 
 }
 

  

 

 package org.leiwen.struts2.aware;

 

 //Session接口
 
 public interface Session {
 

  Object getAttribute(String name);

 

  void setAttribute(String name, Object value);
 
 }
 

  

 

 package org.leiwen.struts2.aware;

 

 //SessionAware接口
 
 public interface SessionAware {
 

  void setSession(Session session);
 
 }
 

 package org.leiwen.struts2.aware;

 

 //MyAction实现了ApplicationAware和SessionAware两个接口
 
 public class MyAction implements ApplicationAware, SessionAware {
 

  private Application app;

 

  private Session session;

 

  @Override
 
  public void setApplication(Application app) {
 
   this.app = app;
 

  }

 

  @Override
 
  public void setSession(Session session) {
 
   this.session = session;
 

  }

 

  public String getName() {
 
   return app + " " + session + getClass();
 
  }
 

 }

 

  

 

 package org.leiwen.struts2.aware;

 

 //action代理
 
 public class MyActionProxy {
 

  private Object action;

 

  public Object getAction() {
 
   return action;
 
  }
 

  public void setAction(Object action) {
 
   this.action = action;
 
  }
 

 }

 

  

 

 package org.leiwen.struts2.aware;

 

 import org.leiwen.struts2.aware.impl.DefaultApplication;
 
 import org.leiwen.struts2.aware.impl.DefaultSession;
 

 
 public class MyInterceptor {
 

  // 也可以在运行时注入
 
  Application app = new DefaultApplication();
 
  // 也可以在运行时注入
 
  Session session = new DefaultSession();
 

  public void intercept(MyActionProxy actionProxy) {
 
   Object action = actionProxy.getAction();
 
   // 如果传入的action实现了ApplicationAware接口,就向action中传入Application实例。
 
   if (action instanceof ApplicationAware) {
 
    ((ApplicationAware) action).setApplication(app);
 
   }
 

   // 如果传入的action实现了SessionAware接口,就向action中传入Session实例。
 
   if (action instanceof SessionAware) {
 
    ((SessionAware) action).setSession(session);
 
   }
 

  }
 
 }
 

  

 

 package org.leiwen.struts2.aware.impl;

 

 import org.leiwen.struts2.aware.Application;

 

 //Application接口的默认实现类
 
 public class DefaultApplication implements Application {
 

  @Override
 
  public String getName() {
 
   return "DefaultApplication";
 
  }
 

  
 
 }
 
 package org.leiwen.struts2.aware.impl;
 

 import java.util.HashMap;
 
 import java.util.Map;
 

 import org.leiwen.struts2.aware.Session;

 

 //Session接口的默认实现类
 
 public class DefaultSession implements Session {
 

  private Map<String, Object> context = new HashMap<String, Object>();

 

  @Override
 
  public Object getAttribute(String name) {
 
   return context.get(name);
 
  }
 

  @Override
 
  public void setAttribute(String name, Object value) {
 
   context.put(name, value);
 
  }
 

 }
 
 package org.leiwen.struts2.aware;
 

 public class AwareTest {

 

  // 测试
 
  public static void main(String[] args) {
 
   //构造action和actionProxy
 
   MyAction action = new MyAction();
 
   MyActionProxy actionProxy = new MyActionProxy();
 
   actionProxy.setAction(action);
 

   //构造拦截器,调用拦截器的intercept方法
 
   MyInterceptor interceptor = new MyInterceptor();
 
   interceptor.intercept(actionProxy);
 
   System.out.println("MyAction的name:" + action.getName());
 
  }
 

 }

  一共4个接口,6个类。