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

最近在做一个数据对接项目,通过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的配置就可以了。

时间: 2024-10-25 05:09:26

通过SpringAOP+注解实现自动代理的相关文章

spring(AOP,基于代理AOP实现,自动代理AOP实现,基于AspectJAOP[注解]实现)

----------------AOP------------------ ----------------------基于代理的AOP实现------------------------------------- 1.创建接口类,实现类 2.引入spring支持,勾选AOP支持 3.创建实现类的bean,代理类的bean 4.创建代理类并实现一下两个接口 5.定义切入点 6.定义通知(绑定一个代理),advice--->代理类,pointcut----->切入点 7.定义代理工厂 targe

springAop注解式Demo

package AnnoAspect.Aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * 切面类 */ @Component @Aspect public class MyAspect2 { /** * 前置通知 */ @Before(value = "exe

spring8——AOP之Bean的自动代理生成器

对于上篇博客http://www.cnblogs.com/cdf-opensource-007/p/6464237.html结尾处提到的两个问题,可以使用spring提供的自动代理生成器解决.自动代理生成器可以让我们把切面织入目标对象方法时不用再使用ProxyFactoryBean这个类来生成代理对象了,同时可以把切面织入多个代理代理对象,并且在获取代理对象时使用的是目标对象的id来获取,这符合正常的使用习惯. spring提供了两个自动代理生成器,一个是DefaultAdvisorAutoPr

自动代理生成器

public interface ISomeService { public void doSome(); public void doSecont(); } 类 public class MyAfterReturningAdvice implements AfterReturningAdvice { public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable

@Resource注解完成自动装配

@Resource注解是通过名字来自动装配的.在spring中自动装配的模式如果是通过名字来自动装配那么必须保证bean的名字和pojo 的属性名一直. 下面是详细代码:说明了@Resource注解是通过名字来完成自动装配的,可以说@Resource注解在某些情况下可以代替@Autowired(通过类型)注解. Address类的代码如下: package com.timo.domain; import org.springframework.beans.BeansException; impo

SSM-Spring-15:Spring中名称自动代理生成器BeanNameAutoProxyCreator

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 名称自动代理生成器:BeanNameAutoProxyCreator 为了更好的测试,我放了俩个接口,俩个实现类: ISomeService接口: package cn.dawn.day18auto02; /** * Created by Dawn on 2018/3/8. */ public interface ISomeService { public void insert(); public voi

SSM-Spring-14:Spring中默认自动代理DefaultAdvisorAutoProxyCreator

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 默认自动代理DefaultAdvisorAutoProxyCreator 本处没有什么要讲的,放原代码 ISomeService接口: package cn.dawn.day17atuo01; /** * Created by Dawn on 2018/3/8. */ public interface ISomeService { public void insert(); public void dele

使用Java注解开发自动生成SQL

使用注解开发的好处就是减少配置文件的使用.在实际过程中,随着项目越来越复杂,功能越来越多,会产生非常多的配置文件.但是,当配置文件过多,实际维护过程中产生的问题就不容易定位,这样就会徒劳的增加工作量.而使用注解开发,可以减少配置文件的使用,方便代码的维护,同时,在开发速度上也有大幅提升,因此,学会使用注解开发,是有必要掌握的一项技能. 下面为各位展示下使用注解开发自动生成SQL语句的过程. 首先先定义一个实体类,用于和数据库字段进行映射,为了方便,数据库字段名称和实体类变量名称保持一致. pac

redsocks2 自动代理设置

redsock2 可以把一些不支持透明代理的代理服务器重定向一下,这样可以实现透明代理了 redsock2安装很简单直接make就可以了, ubuntu需要 apt-get intsll libevent-2.0-5 libssl-dev 安装完成后,直接把 redsocks2 复制到相关目录即可. 我这用它做网关, 然后测试了一下,http 和 https 不能一起走,要分开 #http.conf base {   log_debug = off;    log_info = off;   d