通过SpringAOP+注解实现自动代理

来源:互联网 发布:基础设施网络建设 编辑:程序博客网 时间:2024/06/05 18:21

最近在做一个数据对接项目,通过Hessian与其他企业对接数据。但是公司电脑不能上网只能通过代理上网。如果每个方法都写代理的代码太繁琐,而且项目发布到服务器上的时候服务器是可以上网的。即便通过配置文件配置各个类是否使用代理,但是当发布的时候修改配置文件的内容也会比较多。所以就想到了通过注解+AOP的方式实现自动调用代理。

HTTP代理接口如下,其中的startProxy()为开始使用代理,endProxy()为结束使用代理,在需要用到的时候开启,不用的时候关闭,这样避免其他不需要使用代理的接口出现问题。

package com.tiamaes.gjds.proxy;/**   * <p>类描述: Http代理接口</p> * <p>创建人:王成委  </p> * <p>创建时间:2015年1月16日 上午9:00:53  </p> * <p>版权说明: © 2015 Tiamaes </p> */public interface HttpProxy {    public void startProxy();    public void endProxy();    public String getUsername();    public void setUsername(String username);    public String getPassword();    public void setPassword(String password);    public String getHost();    public void setHost(String host);    public int getPort();    public void setPort(int port);}

实现类如下

package com.tiamaes.gjds.proxy;import java.net.Authenticator;import java.net.PasswordAuthentication;/**   * <p>类描述: Http代理</p> * <p>创建人:王成委  </p> * <p>创建时间:2015年1月15日 下午5:09:16  </p> * <p>版权说明: © 2015 Tiamaes </p> */public class ProxyAuthentication extends Authenticator implements HttpProxy{    private String username;    private String password;    private String host;    private int port;    public ProxyAuthentication(){    }    public ProxyAuthentication(String host,int port){        this.host = host;        this.port = port;    }    public ProxyAuthentication(String host,int port,String username,String password){        this.host = host;        this.port = port;        this.username = username;        this.password = password;    }    public PasswordAuthentication getPasswordAuthentication(){        return new PasswordAuthentication(username,password.toCharArray());    }    /**     * 开始使用代理     * @author 王成委     */    public void startProxy(){        System.setProperty("http.proxySet", "true");        System.setProperty("http.proxyHost", host);        System.setProperty("http.proxyPort", String.valueOf(port));        if(username != null && !"".equals(username))            Authenticator.setDefault(this);    }    /**     * 停止使用代理     * @author 王成委     */    public void endProxy(){        //System.se        System.setProperty("http.proxySet", "false");        System.setProperty("http.proxyHost", "");        System.setProperty("http.proxyPort", "");        Authenticator.setDefault(null);    }    public String getUsername() {        return username;    }    public void setUsername(String username) {        this.username = username;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public String getHost() {        return host;    }    public void setHost(String host) {        this.host = host;    }    public int getPort() {        return port;    }    public void setPort(int port) {        this.port = port;    }}

注解的代码如下

package com.tiamaes.gjds.dxp.annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/**   * <p>类描述: 使用代理设置 </p> * <pre>:eg * @UseProxy * public Object getByHttp(){ *  ...... * } * </pre> * <p>创建人:王成委  </p> * <p>创建时间:2015年2月9日 下午4:41:27  </p> * <p>版权说明: © 2015 Tiamaes </p> * @see com.tiamaes.gjds.dxp.aop.ProxyManager *  */@Target({ElementType.PARAMETER, ElementType.METHOD})  @Retention(RetentionPolicy.RUNTIME)  @Documentedpublic @interface UseProxy {}

AOP切面的代码如下,这个是核心代码,原理就是监控带有UseProxy注解的方法,在方法执行前调用startProxy启动代理在方法执行结束后调用endProxy结束代理。

package com.tiamaes.gjds.dxp.aop;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import com.tiamaes.gjds.proxy.HttpProxy;/**   * <p>类描述: 通过注解{@link com.tiamaes.gjds.dxp.annotation.UseProxy}配置方法使用Http代理 </p> * <p>创建人:王成委  </p> * <p>创建时间:2015年2月9日 下午4:42:06  </p> * <p>版权说明: © 2015 Tiamaes </p> * @see com.tiamaes.gjds.dxp.annotation.UseProxy */@Aspectpublic class ProxyManager {    private HttpProxy httpProxy;    private boolean proxyEnabled = true;    public void setHttpProxy(HttpProxy httpProxy) {        this.httpProxy = httpProxy;    }    public void setProxyEnabled(boolean proxyEnabled) {        this.proxyEnabled = proxyEnabled;    }    @Pointcut("@annotation(com.tiamaes.gjds.dxp.annotation.UseProxy)")      public void proxyAspect() {    }    @Around("proxyAspect()")    public Object doInvoke(ProceedingJoinPoint joinPoint) throws Throwable{        if(httpProxy == null || !proxyEnabled){            return joinPoint.proceed();        }        this.httpProxy.startProxy();        Object result = joinPoint.proceed();        this.httpProxy.endProxy();        return result;    }}

Spring配置如下

    <bean id="httpProxy" class="com.tiamaes.gjds.proxy.ProxyAuthentication">        <property name="host" value="192.168.38.69"/>        <property name="port" value="808" />        <property name="username" value="user001" />        <property name="password" value="123456" />    </bean>    <bean id="proxyManager" class="com.tiamaes.gjds.dxp.aop.ProxyManager">        <property name="httpProxy" ref="httpProxy" />    </bean>

使用方法如下

    @UseProxy    @Override    public List<DriverInfo> GetDriverInfos(List<QueryInfo> queryInfos,            int page, int pageSize) throws HessianException{        List<DriverInfo> drivers = null;        try {            KeliDriverQueryApi api = this.createApiByUrlKey(KeliDriverQueryApi.API_URL, KeliDriverQueryApi.class);            drivers = api.GetDriverInfos(queryInfos, page, pageSize);        } catch (MalformedURLException e) {            throw new ConnotGetHessianApiException("无法创建远程接口");        }        return drivers;    }

只需要在方法上面加一个注解就可以实现自动调用HTTP代理。在不需要HTTP代理的时候直接把Spring配置文件中关的内容删掉就可以了,其实直接删除ProxyManager的配置就可以了。

0 0
原创粉丝点击