2016-06-27 9 views
1

나는 decorate 인터페이스 PreparedStatement을 주문 마무리하기 위해 (단지 예를 들면)하고 싶습니다.자바 7 - 기본, 모든 다른, 많은 방법을 위임하지 않고 사용자 정의 메서드 장식

즉, close()이 호출 될 때 PreparedStatement의 기존 인스턴스를 꾸미므로 다른 코드를 호출하려고합니다. here 일을 좋아하는 들어

, 나는, 단지 내부 객체에 대한 호출을 위임 할 모든 수십에게 PreparedStatement 장식의 방법을 구현 기본적으로해야합니다. 몰락은 단지 부가 가치가없는 많은 일과 코드 일 뿐이라는 것입니다.

또 다른 옵션은 단일 메소드의 모든 메소드에 대한 위임을 수행하는 기본 구현을 제공하기 위해 Java의 Proxy and InvocationHandler을 사용하는 것입니다. 사용자 지정 메서드가있는 경우 InvocationHandler은 호출을 호출합니다. 예 : here을 참조하십시오. 이 솔루션의 문제점은 @Override으로 표시 할 수없고 프록시가 인스턴스화 할 수없는 추상 PreparedStatement을 필요로하기 때문에 해당 서명의 정확성을 검사 할 수 없다는 것입니다.

이렇게 할 수 있습니까? 방법?

* Java 7 max를 사용하여 구현할 수 있어야하지만 Java 8 응답을 제공해야합니다.

+0

사용자 정의 폐쇄에 의해 무슨 소리를, 당신은 더 많은 그것을 설명하십시오 수 있습니다. – PyThon

+0

Mockito를 사용할 수 있습니까? –

+0

AOP를 사용하여 기능을 수행 할 수 있습니다. 그러나 하나의 질문, 왜 당신은'PreparedStatement'를 꾸밀 필요가 있습니까? – Dimitri

답변

0

당신이 인터페이스 PreparedStatement 구체적인 구현을 제공하려는 이해까지. 내가 생각할 수있는 유일한 방법은 인터페이스를 구현하는 추상 클래스를 작성하는 것이다. 그렇게하면 인터페이스에서 모든 메소드를 구현할 필요가 없기 때문에 원하는 구현을 갖게됩니다.

나는 이런 식으로 뭔가를 시도 할 것입니다 : 당신이 그들과 함께 일반적인 상속 일을하기 위해 메소드에 액세스 할 수없는 경우

public abstract class MyPreparedStatement implements PreparedStatement { 

@Override 
public void close() throws SQLException { 
    System.out.println("Closing"); 
} 

public static void main(String[] args) throws SQLException { 
    Connection con = null; 
    MyPreparedStatement statement = (MyPreparedStatement) con.prepareStatement("sql"); 
} 
} 
+2

'Decorator' 개념을 놓친 것 같습니다. 내가받은 PreparedStatement의 인스턴스를 제어하지 못한다. 나는 그것을 사용하는 방법을 제어한다. 솔루션 결과는 ClassCastException이됩니다. –

+0

예, 죄송합니다. 실은 놓치 셨습니다. – Ivo

-1

, 당신은 당신이 할하려는 것을 달성 할 수 Aspect Oriented Programming, AspectJ 또는 Spring Framework aspect 기능을 활용하여 원하는 메소드에 대한 조언을 제공하십시오.

간단한 측면은 기본적으로 내려 온다 : 당신이 함께 귀하의 측면을 일단

@Aspect 
public class MyAspect { 

    @Pointcut("execution(* *(..))") //Replace expression with target method; this example 
    //will hit literally every method ever. 
    public void targetmethod() {}; //Intentionally blank. 
    //AspectJ uses byte code manipulation (or "black magic voodoo", if you 
    // will) to make this method a surrogate for any real one that matches the pointcut 

    @Before("targetmethod()") //Or @After, or @Around, etc... 
    public void doStuff() throws Throwable { 
     //Put your code here 
    } 
} 

, 당신의 aop.xml에 추가하고 당신의 측면을 짜 (당신은 적절한 빌드 관리 프로그램 구성과 컴파일시에이 작업을 수행 할 수 있습니다 또는 java -javaagent:/path/to/aspectjweaver.jar으로 aspectjweaver를 실행하여 런타임에).

그러나 여기에는 java. * 클래스에 대해 이와 같은 작업을 수행하면 소개하는 모든 부작용으로 새롭고 흥미로운 방식으로 문제를 해결할 수 있습니다 (사실, AspectJWeaver는 Java로 짜 넣기를 거부합니다.) . * 클래스는 기본적으로이 클래스를 재정의 할 수 있습니다. 자신이하는 일에 대해 잘 알고 자신의 측면과 aspected 방법을 현명하게 사용하십시오.

+0

'@ Override'를 사용하는 close 메소드의 정확한 서명은 어디에 있습니까? –

+0

그 방법에 대한 pointcut이 무엇인지 묻고 있습니까? 그것은 당신이 당신의 양상을 만지기를 원하는 어느 가까운 방법에 전적으로 의존합니다. ''call (public java.sql.PreparedStatement + .close (..)) ""와 같은 것은 PreparedStatement 또는의 서브 클래스에서'close()'와 일치해야합니다. [This AspectJ pointcut reference] (https://eclipse.org/aspectj/doc/next/quick5.pdf)가 유용 할 수 있습니다. –

0

Proxy 솔루션은 무엇이 부족한가요?AOP - 억양 '후크'에 의존하는이 같은 고려 : 그 데코레이터를 작성하는 주요 키 때문에

final PreparedStatement original = ...; 
final InvocationHandler delegator = new InvocationHandler() { 

    void onClose() { 
    /* do stuff */ 
    } 

    Object invoke(final Object proxy, final Method method, final Object[] args) { 
    if (method.getName().equals("close")) { 
     onClose(); 
    } 

    return method.invoke(original, args); 
    } 
}; 
final PreparedStatement wrapped = (PreparedStatement) Proxy.newProxyInstance(this.getClass().getClassLoader(), 
    new Class<?>[] { PreparedStatement.class }, delegator); 
+0

토론 된 메서드가 여러 개의 인수를 받았다고 상상해보십시오. 이제 수동으로 args를 변환하지 않기 위해 reflection을 사용하여 custom 메소드를 호출해야합니다. 즉, 컴파일 타임에 아무도 사용자 정의 닫기 메소드를 호출하지 않는다는 의미입니다. 따라서 누군가가 사용자 정의 클로즈 메소드의 서명을 변경할 수 있다고 생각할 수 있습니다. 나의 목적은 커스텀 메소드를 실제 인터페이스'PreparedStatement'에, 바람직하게는'@ Override '로 묶는 것이다. 인터페이스에 사용자 정의 메서드를 연결해야하는 또 다른 이유는 검색을 수행 할 때 찾았습니다. –

+0

@ AlikElzin-kilaka 그런데 분명한 해결책은 이전에 언급 한 것처럼 위임 된 PreparedStatementDecorator를 작성하는 것입니다. 최소한의 오버 헤드로 원하는 모든 것을 성취합니다. – oldrinb