自定义annotation实现注入

阅读更多
1.工程所需要的jar,struts版本struts:1.2.6
commons-beanutils.jar
commons-digester.jar
commons-logging.jar
struts.jar
2.工程代码
package sun.com.struts.action;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.MappingDispatchAction;
import sun.com.struts.pojo.LoginForm;
import sun.com.struts.service.ServiceLocator;
import sun.com.struts.service.UserService;
/**
 * user login action
 * @author fengyilin
 * @version $Revision: 64555 $ $Date: 2012-04-19 15:01:28 +0800 (Thu, 19 Apr 2012) $
 * @since 2012/04/26
 *
 */
public class LoginAction extends MappingDispatchAction {
    /** get the serviceLocator */
    private static ServiceLocator locator = ServiceLocator.getInstance();
    /** user service*/
    private UserService userService = (UserService) locator
            .getService("UserService");
    /**
     * login
     *
     * @param map ActionMapping  
     * @param form ActionForm
     * @param request HttpServletRequest
     * @param response HttpServletResponse
     * @return actionForward
    */
    public ActionForward login(ActionMapping map, ActionForm form,
            HttpServletRequest request, HttpServletResponse response) {
        LoginForm loginForm = (LoginForm) form;  
        String name = loginForm.getName();
        String passWord = loginForm.getPassWord();
        String userName = userService.findUserByName(name);
        if ("lin".equals(userName) && "lin".equals(passWord)) {
            return map.findForward("success");
        } else {
            return map.findForward("input");
        }
    }
}

这个action和普通的struts action的区别在于里面有如下src
 /** get the serviceLocator */
    private static ServiceLocator locator = ServiceLocator.getInstance();
    /** user service*/
    private UserService userService = (UserService) locator
            .getService("UserService");

即用到的service是由serviceLocator这个类提供的,ServiceLocator是自己定义的一个类扫描类,代码会在下面给出。
/**
 * 
 */
package sun.com.struts.annotation.service;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * @author fengyilin
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Service {
    /** service name */
    String value();
}

 /**
 * 
 */
package sun.com.struts.pojo;
import org.apache.struts.action.ActionForm;
/**
 * user login action
 * @author fengyilin
 * @version $Revision: 64555 $ $Date: 2012-04-19 15:01:28 +0800 (Thu, 19 Apr 2012) $
 * @since 2011/08/05
 *
 */
public class LoginForm extends ActionForm {
    /**
     * 
     */
    private static final long serialVersionUID = 7260629305234876476L;
    private String name;
    private String passWord;
    /**
     * @param name
     *            the name to set  
     */
    public void setName(String name) {
        this.name = name;
    }
    /**
     * @return name name
     */
    public String getName() {
        return name;
    }
    /**
     * @param passWord
     *            the passWord to set
     */
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    /**
     * @return the passWord
     */
    public String getPassWord() {
        return passWord;
    }
}


BaseService接口编写,所有的service接口都要继承自这个接口。
/**
 * 
 */
package sun.com.struts.service;
/**
 * @author fengyilin
 *
 */
public interface BaseService {
    /**
     * init the service
     */
    void init ();
    /**
     * destory the service
     */
    void destory();
}


UserService接口编写
/**
 * 
 */
package sun.com.struts.service;
/**
 * @author fengyilin
 *
 */
public interface UserService extends BaseService {
    /**
     * find the user
     * @param name userName
     * @return user
     */
    public String findUserByName(String name);
}

UserServiceImpl编写,该类的特别之处在于声明了Service这个annotation
/**
 * 
 */
package sun.com.struts.service.impl;
import sun.com.struts.annotation.service.Service;
import sun.com.struts.service.UserService;
/**
 * @author fengyilin
 *
 */
@Service("UserService")
public class UserServiceImpl implements UserService {
    @Override
    public void destory() {
    }
    @Override
    public void init() {
    }
    /**
     * find the user
     * @param name userName
     * @return user
     */
    @Override
    public String findUserByName(String name) {
        if ("gaofeng".equals(name)) {
            return "lin";
        } else {
            return "";
        }
    }
}
 

编写本文的重点类,类扫描器,这个类将对src\sun\com\struts\service这个包下的所有的类,然后会判断哪个类定义了Service的annotation,如果定义了,就将该类的一个实例保存到services这个map中。这样我们在action中想用哪一个service,直接从services中get出来就可以了。
/**
 * 
 */
package sun.com.struts.service;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
 * @author fengyilin
 *
 */
public final class ServiceLocator {
    /**
     * annotation path
     *
     * the class witch is belong to this path will be read
     */
    private static final String TARGET_PATH = "sun/com/struts/service/";
  //----------------------------------------------------------------- static 変数
    /** the unique system Locator instance */
    private static ServiceLocator locator = new ServiceLocator();
    /** construct method */
    private ServiceLocator() {}
    /** put the service instance to cache */
    private Map services;
    /** Log instance */
    private static Log log = LogFactory.getLog(ServiceLocator.class);
    /**
     * get the unique system Locator instance
     *
     * @return Locator instance
     */
    public static ServiceLocator getInstance() {
        return locator;
    }
    /** type of the class file */
    private static final String CLASS_EXTENSION = ".class";
    /**
     * get the service.
     *
     * @param  service type
     * @param name service name
     * @return service
     * @see #load()
     */
    public  T getService(String name) {
        if (name == null) {
            return null;
        }
        if (services == null) {
            try {
                log.debug("reade the service...");
                load();
            } catch (Error e) {
                log.error("[BUG] can not reade the service correctly", e);
                services = null;
                throw e;
            } catch (RuntimeException e) {
                log.error("[BUG] can not reade the service correctly", e);
                services = null;
                throw e;
            }
        }
        @SuppressWarnings("unchecked")
        T service = (T) services.get(name);
        return service;
    }
    /**
     * read the service of the path
     */
    private void load() {
        services = new HashMap();
        // get all the class
        try {
            for (Class c : getClasses(TARGET_PATH)) {
                sun.com.struts.annotation.service.Service s = c
                        .getAnnotation(sun.com.struts.annotation.service.Service.class);
                if (s != null) {
                    BaseService service = createBaseService(c);
                    services.put(s.value(), service);
                    log.debug("    [annotation]:" + service);
                }
            }
        } catch (Exception e) {
            log.debug(e);
        }
        log.debug(services);
    }
    /**
     * get the service
     *
     * @param c class
     * @return BaseService service
     * @throws Exception error
     */
    private BaseService createBaseService(Class c) throws Exception {
        try {
            BaseService service = (BaseService)c.newInstance();
            return service;
        } catch (Exception e) {
            e = new ClassCastException(c.getName());
            throw e;
        }
    }
    /**
     * 

* read all the class belong to the path *

* * @param path class path (ex. sun/com/struts/service/) * @return class * @throws Exception error */ public static Class[] getClasses(String path) throws Exception { Enumeration e; try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); e = loader.getResources(path); } catch (IOException ex) { throw new RuntimeException( "can not get the src(" + path + ")", ex); } if (log.isWarnEnabled()) { if (!e.hasMoreElements()) { log.warn("########## [getClasses] the source does not exist" + "(" + path + ")"); } } //buf of the path StringBuilder buf = new StringBuilder(); Set> classes = new LinkedHashSet>(); while (e.hasMoreElements()) { URL url = e.nextElement(); if (log.isDebugEnabled()) { log.debug("########## [getClasses] " + url); } // get the of the path File file = new File(url.getFile()); URI uri = file.toURI(); for (File f : listFiles(file)) { buf.setLength(0); classes.add(forClass(buf.append(path) .append(uri.relativize(f.toURI()).getPath()) .toString())); } } return classes.toArray(new Class[classes.size()]); } /** * get the next flow of the directory * return the directory * * @param file file * @return directory list */ private static List listFiles(File file) { List files = new ArrayList(); // class file if (file.getName().endsWith(CLASS_EXTENSION)) { files.add(file); } // next flow is exit File[] fs = file.listFiles(); if (fs != null) { for (File f : file.listFiles()) { files.addAll(listFiles(f)); } } return files; } /** * get the object of the path * * Class c = forClass("sun/com/struts/service/BaseService.class"); * * equlesWith * * Class c = Class.forName("sun.com.struts.service.BaseService"); * * @param path class * @return object * @throws Exception error */ private static Class forClass(final String path) throws Exception { String name = toClassName(path); if (log.isDebugEnabled()) { log.debug("########## [forClass] " + path); } try { return Class.forName(name, false, Thread.currentThread().getContextClassLoader()); } catch (ClassNotFoundException e) { if (log.isWarnEnabled()) { log.warn("########## [forClass] " + name + " does not exict。", e); } return null; } catch (ExceptionInInitializerError e) { log.error(name + " can not init。", e); throw new Exception(path, e); } catch (NoClassDefFoundError e) { log.error(name + " does not exict。", e); throw new Exception(path, e); } } /** * convert the path。 * * @param path class path (ex. sun/com/struts/service/BaseService.class); * @return the class name (ex. sun.com.struts.service.BaseService) */ private static String toClassName(String path) { if (!path.endsWith(CLASS_EXTENSION)) { throw new IllegalArgumentException( "[BUG]type is not the\"" + CLASS_EXTENSION + " (" + path + ")"); } return path.substring(0, path.length() - CLASS_EXTENSION.length()).replace("/", "."); } }

编写配置文件。struts-config.xml



  
  
      
    
      
      
    
  
    
  
    
    
      
      
    
    
 

修改web.xml添加struts1的支持。


 
 myStruts1
    
    
        action
        org.apache.struts.action.ActionServlet
        
            config
            /WEB-INF/struts-config.xml
        
        
            debug
            2
        
        
            detail
            2
        
        2
    
    
    
        action
        /action/*
    
 
  login.jsp
 

login.jsp
<%@ page language="java" contentType="text/html; charset=windows-31j"
    pageEncoding="windows-31j"%>




Login Home


name
passWord
submit

你可能感兴趣的:(struts)