通過 Spring AOP 註解實現自動代理
最近在做一個資料對接專案,通過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) @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的配置就可以了。
相關文章
- Spring AOP 自動建立代理Spring
- Spring 註解方式實現的AOPSpring
- Spring AOP 實現《自動自動填充Entity》Spring
- Spring中通過Annotation來實現AOPSpring
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- Spring Aop基於註解的實現Spring
- Spring Boot系列十八 Spring AOP + 註解實現統一註解Spring Boot
- Spring實現無需註解實現自動注入Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(一)入口Spring
- spring上 -基於註解配置bean,動態代理,AOP筆記SpringBean筆記
- Spring框架系列(10) - Spring AOP實現原理詳解之AOP代理的建立Spring框架
- Spring系列之aAOP AOP是什麼?+xml方式實現aop+註解方式實現aopSpringXML
- Spring MVC AOP通過自定義註解方式攔截Controller等實現日誌管理SpringMVCController
- Spring框架系列(12) - Spring AOP實現原理詳解之JDK代理實現Spring框架JDK
- 淺析Spring中AOP的實現原理——動態代理Spring
- Spring AOP實現過程Spring
- spring通過註解配置Spring
- Spring框架系列(11) - Spring AOP實現原理詳解之Cglib代理實現Spring框架CGLib
- spring-AOP(二)實現原理之AspectJ註解方式Spring
- 死磕Spring之AOP篇 - Spring AOP註解驅動與XML配置SpringXML
- Spring AOP的AspectJ註解Spring
- spring 05 aop_註解Spring
- Spring AOP --JDK動態代理方式SpringJDK
- 運用Spring Aop,一個註解實現日誌記錄Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(二)篩選合適的通知器Spring
- 菜鳥學SSH(十四)——Spring容器AOP的實現原理——動態代理Spring
- Spring框架系列(9) - Spring AOP實現原理詳解之AOP切面的實現Spring框架
- spring框架半自動註解Spring框架
- Spring5(七)——AOP註解Spring
- Spring-Aop註解形式案例Spring
- Spring Boot中自定義註解+AOP實現主備庫切換Spring Boot
- Spring AOP整合redis(註解方式) 實現快取統一管理SpringRedis快取
- 從動態代理到Spring AOP(上)Spring
- 從動態代理到Spring AOP(中)Spring
- Spring——AOP實現Spring
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- spring通過註解註冊bean的方式+spring生命週期SpringBean
- Spring AOP裡的靜態代理和動態代理,你真的瞭解嘛?Spring