通過 Spring AOP 注解實現自動代理
最近在做一個數據對接項目,通過Hessian與其他企業對接數據。但是公司電腦不能上網只能通過DL上網。如果每個方法都寫代理的代碼太繁瑣,而 且項目發布到服務器上的時候服務器是可以上網的。即便通過配置文件配置各個類是否使用代理,但是當發布的時候修改配置文件的內容也會比較多。所以就想到了 通過注解+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) @Documented public @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 */ @Aspect public 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的配置就可以了。
來源:王成委的博客
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!