IntelliJ IDEAでProxyクラスを自動作成する方法

#そもそも、Proxyクラスとは？

メソッドの実行前後に何か処理させたいって時に使うものっすね。
例えば、こんなの↓を実装できたりします。
[java.sql.Connectionプロキシの素 - Qiita](https://qiita.com/momosetkn/items/4a6bb729b793a75d2fa2)

しかし、インターフェイスによってはメソッド数が多すぎて
一つ一つ手で作っていったら何か間違いが起きそうで🍣、
IDEで自動生成しちゃいましょう。

## 余談
プロキシは↓のように他にも方法が色々あるので、まずはどれがいいか検討してみよう。

- [java.lang.reflect.Proxy](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/reflect/Proxy.html)でプログラムチックにプロキシ作るのも手
- SpringなどのFWを使ってAOPして、FWのやり方にはめるのも手

#さあ、IntelliJ IDEAの機能で早速作ってみるぞ
`HttpServletRequest`というインターフェイスを例にやってみます。

##1. まずは以下のようなプロキシの元となるコードを書きましょう。

インターフェイスをimplementsしたクラスを作ってください。
そして、プロキシの元となるフィールドとコンストラクタ―を書いてください。

![キャプチャ_0.PNG](https://qiita-image-store.s3.amazonaws.com/0/196806/da717226-06b4-5e8c-b9de-f5a71f80f5ac.png)

```java
import javax.servlet.http.HttpServletRequest;

public class HttpServletRequestProxy2 implements HttpServletRequest {
    private HttpServletRequest delegate;

    public HttpServletRequestProxy2(HttpServletRequest delegate){
        this.delegate = delegate;
    }

}
```

##2. クラス名にカーソルを置いた状態で<kbd><kbd>Alt<kbd> + </kbd>Insert</kbd></kbd>を押して`Delegate Methods...`を押す

![QS_20180514-105111.png](https://qiita-image-store.s3.amazonaws.com/0/196806/78c6df25-c0db-5dc7-18e7-c003fd0c5dad.png)

##3.さっきのプロキシの元とするフィールドを1個選択する

![QS_20180514-105122.png](https://qiita-image-store.s3.amazonaws.com/0/196806/38f9dcd4-e75d-7b9a-670f-24be640b0b25.png)

##4. 生成するメソッドを選択する(基本的には<kbd><kbd>Alt<kbd> + </kbd>A</kbd></kbd>で全選択してOK）

![QS_20180514-105151.png](https://qiita-image-store.s3.amazonaws.com/0/196806/68895f74-2617-c513-5e45-add989970527.png)

##完成

![キャプチャ_1.PNG](https://qiita-image-store.s3.amazonaws.com/0/196806/66d8a145-5f00-009e-8c79-4969ed9687b1.png)

```java
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;

public class HttpServletRequestProxy implements HttpServletRequest {
    private HttpServletRequest delegate;

    public HttpServletRequestProxy(HttpServletRequest delegate){
        this.delegate = delegate;
    }

    @Override
    public String getAuthType() {
        return delegate.getAuthType();
    }

    @Override
    public Cookie[] getCookies() {
        return delegate.getCookies();
    }

    @Override
    public long getDateHeader(String name) {
        return delegate.getDateHeader(name);
    }

    @Override
    public String getHeader(String name) {
        return delegate.getHeader(name);
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        return delegate.getHeaders(name);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        return delegate.getHeaderNames();
    }

    @Override
    public int getIntHeader(String name) {
        return delegate.getIntHeader(name);
    }

    @Override
    public String getMethod() {
        return delegate.getMethod();
    }

    @Override
    public String getPathInfo() {
        return delegate.getPathInfo();
    }

    @Override
    public String getPathTranslated() {
        return delegate.getPathTranslated();
    }

    @Override
    public String getContextPath() {
        return delegate.getContextPath();
    }

    @Override
    public String getQueryString() {
        return delegate.getQueryString();
    }

    @Override
    public String getRemoteUser() {
        return delegate.getRemoteUser();
    }

    @Override
    public boolean isUserInRole(String role) {
        return delegate.isUserInRole(role);
    }

    @Override
    public Principal getUserPrincipal() {
        return delegate.getUserPrincipal();
    }

    @Override
    public String getRequestedSessionId() {
        return delegate.getRequestedSessionId();
    }

    @Override
    public String getRequestURI() {
        return delegate.getRequestURI();
    }

    @Override
    public StringBuffer getRequestURL() {
        return delegate.getRequestURL();
    }

    @Override
    public String getServletPath() {
        return delegate.getServletPath();
    }

    @Override
    public HttpSession getSession(boolean create) {
        return delegate.getSession(create);
    }

    @Override
    public HttpSession getSession() {
        return delegate.getSession();
    }

    @Override
    public boolean isRequestedSessionIdValid() {
        return delegate.isRequestedSessionIdValid();
    }

    @Override
    public boolean isRequestedSessionIdFromCookie() {
        return delegate.isRequestedSessionIdFromCookie();
    }

    @Override
    public boolean isRequestedSessionIdFromURL() {
        return delegate.isRequestedSessionIdFromURL();
    }

    @Override
    public boolean isRequestedSessionIdFromUrl() {
        return delegate.isRequestedSessionIdFromUrl();
    }

    @Override
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
        return delegate.authenticate(response);
    }

    @Override
    public void login(String username, String password) throws ServletException {
        delegate.login(username, password);
    }

    @Override
    public void logout() throws ServletException {
        delegate.logout();
    }

    @Override
    public Collection<Part> getParts() throws IOException, ServletException {
        return delegate.getParts();
    }

    @Override
    public Part getPart(String name) throws IOException, ServletException {
        return delegate.getPart(name);
    }

    @Override
    public Object getAttribute(String name) {
        return delegate.getAttribute(name);
    }

    @Override
    public Enumeration<String> getAttributeNames() {
        return delegate.getAttributeNames();
    }

    @Override
    public String getCharacterEncoding() {
        return delegate.getCharacterEncoding();
    }

    @Override
    public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
        delegate.setCharacterEncoding(env);
    }

    @Override
    public int getContentLength() {
        return delegate.getContentLength();
    }

    @Override
    public String getContentType() {
        return delegate.getContentType();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        return delegate.getInputStream();
    }

    @Override
    public String getParameter(String name) {
        return delegate.getParameter(name);
    }

    @Override
    public Enumeration<String> getParameterNames() {
        return delegate.getParameterNames();
    }

    @Override
    public String[] getParameterValues(String name) {
        return delegate.getParameterValues(name);
    }

    @Override
    public Map<String, String[]> getParameterMap() {
        return delegate.getParameterMap();
    }

    @Override
    public String getProtocol() {
        return delegate.getProtocol();
    }

    @Override
    public String getScheme() {
        return delegate.getScheme();
    }

    @Override
    public String getServerName() {
        return delegate.getServerName();
    }

    @Override
    public int getServerPort() {
        return delegate.getServerPort();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return delegate.getReader();
    }

    @Override
    public String getRemoteAddr() {
        return delegate.getRemoteAddr();
    }

    @Override
    public String getRemoteHost() {
        return delegate.getRemoteHost();
    }

    @Override
    public void setAttribute(String name, Object o) {
        delegate.setAttribute(name, o);
    }

    @Override
    public void removeAttribute(String name) {
        delegate.removeAttribute(name);
    }

    @Override
    public Locale getLocale() {
        return delegate.getLocale();
    }

    @Override
    public Enumeration<Locale> getLocales() {
        return delegate.getLocales();
    }

    @Override
    public boolean isSecure() {
        return delegate.isSecure();
    }

    @Override
    public RequestDispatcher getRequestDispatcher(String path) {
        return delegate.getRequestDispatcher(path);
    }

    @Override
    public String getRealPath(String path) {
        return delegate.getRealPath(path);
    }

    @Override
    public int getRemotePort() {
        return delegate.getRemotePort();
    }

    @Override
    public String getLocalName() {
        return delegate.getLocalName();
    }

    @Override
    public String getLocalAddr() {
        return delegate.getLocalAddr();
    }

    @Override
    public int getLocalPort() {
        return delegate.getLocalPort();
    }

    @Override
    public ServletContext getServletContext() {
        return delegate.getServletContext();
    }

    @Override
    public AsyncContext startAsync() throws IllegalStateException {
        return delegate.startAsync();
    }

    @Override
    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
        return delegate.startAsync(servletRequest, servletResponse);
    }

    @Override
    public boolean isAsyncStarted() {
        return delegate.isAsyncStarted();
    }

    @Override
    public boolean isAsyncSupported() {
        return delegate.isAsyncSupported();
    }

    @Override
    public AsyncContext getAsyncContext() {
        return delegate.getAsyncContext();
    }

    @Override
    public DispatcherType getDispatcherType() {
        return delegate.getDispatcherType();
    }
}
```