diff --git a/src/main/java/com/aliyun/oss/ClientConfiguration.java b/src/main/java/com/aliyun/oss/ClientConfiguration.java
index d2d4a44d..1cc32689 100644
--- a/src/main/java/com/aliyun/oss/ClientConfiguration.java
+++ b/src/main/java/com/aliyun/oss/ClientConfiguration.java
@@ -40,6 +40,8 @@
 import com.aliyun.oss.common.comm.SignVersion;
 import com.aliyun.oss.common.utils.ResourceManager;
 import com.aliyun.oss.common.utils.VersionInfoUtils;
+import com.aliyun.oss.endpoint.DefaultEndpointResolver;
+import com.aliyun.oss.endpoint.EndpointResolver;
 import com.aliyun.oss.internal.OSSConstants;
 
 /**
@@ -127,6 +129,10 @@ public class ClientConfiguration {
 
     private boolean tracerEnabled = false;
 
+    private boolean isRefreshEndpointAddr = false;
+
+    private EndpointResolver endpointResolver = new DefaultEndpointResolver();
+
     public ClientConfiguration() {
         super();
         AppendDefaultExcludeList(this.cnameExcludeList);
@@ -991,4 +997,41 @@ public boolean isTracerEnabled() {
     public void setTracerEnabled(boolean enabled) {
         this.tracerEnabled = enabled;
     }
+
+    /**
+     * Gets the flag of refresh endpoint.
+     *
+     * @return  True if it's enabled; False if it's disabled.
+     */
+    public boolean isRefreshEndpointAddr() {
+        return isRefreshEndpointAddr;
+    }
+
+    /**
+     * Sets the flag of refresh endpoint.
+     *
+     * @param refreshEndpointAddr True if it's enabled; False if it's disabled.
+     */
+    public void setRefreshEndpointAddr(boolean refreshEndpointAddr) {
+        isRefreshEndpointAddr = refreshEndpointAddr;
+    }
+
+    /**
+     * Gets the endpoint resolver.
+     *
+     * @return endpoint resolver.
+     */
+    public EndpointResolver getEndpointResolver() {
+        return endpointResolver;
+    }
+
+    /**
+     * Sets the endpoint resolver.
+     *
+     * @param endpointResolver
+     */
+    public void setEndpointResolver(EndpointResolver endpointResolver) {
+        this.endpointResolver = endpointResolver;
+    }
+
 }
diff --git a/src/main/java/com/aliyun/oss/common/comm/ServiceClient.java b/src/main/java/com/aliyun/oss/common/comm/ServiceClient.java
index 4a683c2e..71707124 100644
--- a/src/main/java/com/aliyun/oss/common/comm/ServiceClient.java
+++ b/src/main/java/com/aliyun/oss/common/comm/ServiceClient.java
@@ -28,8 +28,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
+import java.net.URI;
 import java.util.List;
 
+import com.aliyun.oss.internal.OSSUtils;
 import org.apache.http.HttpMessage;
 
 import com.aliyun.oss.ClientConfiguration;
@@ -120,6 +122,9 @@ private ResponseMessage sendRequestImpl(RequestMessage request, ExecutionContext
         while (true) {
             try {
                 if (retries > 0) {
+                    if (config.isRefreshEndpointAddr()) {
+                        refreshEndpointAddr(request);
+                    }
                     pause(retries, retryStrategy);
                     if (requestContent != null && requestContent.markSupported()) {
                         try {
@@ -392,4 +397,17 @@ public void setUseChunkEncoding(boolean useChunkEncoding) {
             this.useChunkEncoding = useChunkEncoding;
         }
     }
+
+    public void refreshEndpointAddr(RequestMessage request)
+            throws ServiceException, ClientException {
+        String endpoint = "";
+        if (config.isSupportCname()){
+            endpoint = config.getEndpointResolver().resolveGetServiceApiEndpoint(request.getEndpoint().toString());
+        } else {
+            endpoint = config.getEndpointResolver().resolveGeneralApiEndpoint(request.getEndpoint().toString());
+        }
+        String defaultProto = config.getProtocol().toString();
+        URI uri = OSSUtils.toEndpointURI(endpoint, defaultProto);
+        request.setEndpoint(uri);
+    }
 }
diff --git a/src/main/java/com/aliyun/oss/endpoint/DefaultEndpointResolver.java b/src/main/java/com/aliyun/oss/endpoint/DefaultEndpointResolver.java
new file mode 100644
index 00000000..b3ea42a5
--- /dev/null
+++ b/src/main/java/com/aliyun/oss/endpoint/DefaultEndpointResolver.java
@@ -0,0 +1,19 @@
+
+package com.aliyun.oss.endpoint;
+
+/**
+ * default endpoint resolver, just return the api endpoint
+ * the dns resolve will be implemented by http library.
+ */
+public class DefaultEndpointResolver implements EndpointResolver {
+
+    @Override
+    public String resolveGeneralApiEndpoint(String generalApiEndpoint) {
+        return generalApiEndpoint;
+    }
+
+    @Override
+    public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint) {
+        return getServiceApiEndpoint;
+    }
+}
diff --git a/src/main/java/com/aliyun/oss/endpoint/EndpointResolver.java b/src/main/java/com/aliyun/oss/endpoint/EndpointResolver.java
new file mode 100644
index 00000000..e77df5cf
--- /dev/null
+++ b/src/main/java/com/aliyun/oss/endpoint/EndpointResolver.java
@@ -0,0 +1,26 @@
+package com.aliyun.oss.endpoint;
+
+/**
+ * resolve the endpoint like dns.
+ *
+ */
+
+public interface EndpointResolver {
+    /**
+     * return the general api endpoint, the result can be ip or ip:port. if you don't do
+     * anything like DefaultEndpointResolver. the http library will implement the dns resolve.
+     * 
+     * @param generalApiEndpoint
+     * @return the endpoint addr
+     */
+    public String resolveGeneralApiEndpoint(String generalApiEndpoint);
+
+    /**
+     * return the get service api endpoint, the result can be ip or ip:port. if you don't do
+     * anything like DefaultEndpointResolver. the http library will implement the dns resolve.
+     * 
+     * @param getServiceApiEndpoint
+     * @return the endpoint
+     */
+    public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint);
+}
diff --git a/src/main/java/com/aliyun/oss/internal/OSSOperation.java b/src/main/java/com/aliyun/oss/internal/OSSOperation.java
index a73eec7f..98760d05 100644
--- a/src/main/java/com/aliyun/oss/internal/OSSOperation.java
+++ b/src/main/java/com/aliyun/oss/internal/OSSOperation.java
@@ -91,6 +91,14 @@ public URI getEndpoint() {
 
     public URI getEndpoint(WebServiceRequest request) {
         String reqEndpoint = request.getEndpoint();
+        if (client.getClientConfiguration().isRefreshEndpointAddr()) {
+            if (client.getClientConfiguration().isSupportCname()){
+                reqEndpoint = client.getClientConfiguration().getEndpointResolver().resolveGetServiceApiEndpoint(reqEndpoint);
+            } else {
+                reqEndpoint = client.getClientConfiguration().getEndpointResolver().resolveGeneralApiEndpoint(reqEndpoint);
+            }
+        }
+
          if (reqEndpoint == null) {
              return getEndpoint();
 
diff --git a/src/test/java/com/aliyun/oss/common/comm/EndpointRefreshTest.java b/src/test/java/com/aliyun/oss/common/comm/EndpointRefreshTest.java
new file mode 100644
index 00000000..0aa9a89e
--- /dev/null
+++ b/src/test/java/com/aliyun/oss/common/comm/EndpointRefreshTest.java
@@ -0,0 +1,101 @@
+package com.aliyun.oss.common.comm;
+
+import com.aliyun.oss.*;
+import com.aliyun.oss.common.auth.Credentials;
+import com.aliyun.oss.common.auth.DefaultCredentialProvider;
+import com.aliyun.oss.common.auth.DefaultCredentials;
+import com.aliyun.oss.endpoint.EndpointResolver;
+import com.aliyun.oss.integrationtests.TestBase;
+import com.aliyun.oss.integrationtests.TestConfig;
+import junit.framework.Assert;
+import org.junit.Test;
+
+public class EndpointRefreshTest extends TestBase {
+
+	@Test
+    public void testEndpointRefresh() {
+        class CustomEndpointResolver implements EndpointResolver {
+            private String endpoint = null;
+
+            public String getEndpoint() {
+                return endpoint;
+            }
+
+            public void setEndpoint(String endpoint) {
+                this.endpoint = endpoint;
+            }
+
+            @Override
+            public String resolveGeneralApiEndpoint(String generalApiEndpoint) {
+                return this.endpoint;
+            }
+
+            @Override
+            public String resolveGetServiceApiEndpoint(String getServiceApiEndpoint) {
+                return this.endpoint;
+            }
+        }
+
+        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
+        Credentials credentials = new DefaultCredentials(TestConfig.OSS_TEST_ACCESS_KEY_ID, TestConfig.OSS_TEST_ACCESS_KEY_SECRET);
+        OSS client = new OSSClient(TestConfig.OSS_TEST_ENDPOINT, new DefaultCredentialProvider(credentials), conf);
+        Assert.assertEquals(TestConfig.OSS_TEST_ENDPOINT, ((OSSClient) client).getEndpoint().toString());
+
+        CustomEndpointResolver customEndpointResolver = new CustomEndpointResolver();
+
+        // Custom Domain
+        customEndpointResolver.setEndpoint("www.abbbc.com");
+        conf.setSupportCname(true);
+        conf.setRefreshEndpointAddr(true);
+        conf.setEndpointResolver(customEndpointResolver);
+
+        try {
+            client.getObject("bucket","object");
+            System.out.println("ok");
+        } catch (ClientException e) {
+            Assert.assertEquals("www.abbbc.com\n" +
+                    "[ErrorCode]: UnknownHost\n" +
+                    "[RequestId]: Unknown", e.getMessage());
+        }
+
+        // ip
+        customEndpointResolver.setEndpoint("127.0.0.1");
+        conf.setSupportCname(true);
+        conf.setEndpointResolver(customEndpointResolver);
+
+        try {
+            client.getObject("bucket","object");
+            System.out.println("ok");
+        } catch (ClientException e) {
+            Assert.assertEquals("Connect to 127.0.0.1:80 [/127.0.0.1] failed: Connection refused: connect\n" +
+                    "[ErrorCode]: SocketException\n" +
+                    "[RequestId]: Unknown", e.getMessage());
+        }
+
+        // ip:port
+        customEndpointResolver.setEndpoint("127.0.0.1:8080");
+        conf.setSupportCname(true);
+        conf.setEndpointResolver(customEndpointResolver);
+
+        try {
+            client.getObject("bucket","object");
+            System.out.println("ok");
+        } catch (ClientException e) {
+            Assert.assertEquals("Connect to 127.0.0.1:8080 [/127.0.0.1] failed: Connection refused: connect\n" +
+                    "[ErrorCode]: SocketException\n" +
+                    "[RequestId]: Unknown", e.getMessage());
+        }
+
+        // bucket.Domain
+        conf.setSupportCname(false);
+        customEndpointResolver.setEndpoint("aaa.aliyuncs.com");
+        conf.setEndpointResolver(customEndpointResolver);
+        try {
+            client.getObject("bucket","object");
+        } catch (ClientException e) {
+            Assert.assertEquals("aaa.aliyuncs.com\n" +
+                    "[ErrorCode]: UnknownHost\n" +
+                    "[RequestId]: Unknown", e.getMessage());
+        }
+    }
+}
diff --git a/src/test/java/com/aliyun/oss/common/comm/OSSClientTest.java b/src/test/java/com/aliyun/oss/common/comm/OSSClientTest.java
index 9f206be3..105c54e5 100644
--- a/src/test/java/com/aliyun/oss/common/comm/OSSClientTest.java
+++ b/src/test/java/com/aliyun/oss/common/comm/OSSClientTest.java
@@ -30,6 +30,8 @@
 import com.aliyun.oss.common.auth.Credentials;
 import com.aliyun.oss.common.auth.CredentialsProvider;
 import com.aliyun.oss.common.auth.DefaultCredentialProvider;
+import com.aliyun.oss.endpoint.DefaultEndpointResolver;
+import com.aliyun.oss.endpoint.EndpointResolver;
 import com.aliyun.oss.internal.OSSConstants;
 import com.aliyun.oss.internal.RequestParameters;
 import com.aliyun.oss.model.GetObjectRequest;
@@ -482,5 +484,18 @@ public void testExtractSettingFromEndpoint() {
         Assert.assertEquals("region", clientImpl.getObjectOperation().getRegion());
         Assert.assertEquals("oss-cloudbox", clientImpl.getObjectOperation().getProduct());
     }
+
+    @Test
+    public void testConfigurationWithEndpointResolver() {
+        ClientConfiguration clientConfiguration = new ClientConfiguration();
+
+        clientConfiguration.setRefreshEndpointAddr(true);
+        Assert.assertEquals(true, clientConfiguration.isRefreshEndpointAddr());
+
+        DefaultEndpointResolver defaultEndpointResolver = new DefaultEndpointResolver();
+        clientConfiguration.setEndpointResolver(defaultEndpointResolver);
+        Assert.assertEquals(defaultEndpointResolver, clientConfiguration.getEndpointResolver());
+    }
+
 }