通過 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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!