복붙노트

[SPRING] 자바 객체가 런타임에 인터페이스를 구현하도록 할 수 있습니까?

SPRING

자바 객체가 런타임에 인터페이스를 구현하도록 할 수 있습니까?

바로 지금 다음과 같습니다.

1) Java 인터페이스.

2) 전술 한 인터페이스를 구현하지 않고 인터페이스에 정의 된 모든 메소드와 일치하는 메소드 서명을 포함하는 구체적인 Java 클래스.

이후 아이템 2의 구현을 변경할 수 없으므로 클래스 캐스팅 예외없이 아이템 1의 인스턴스를 인수 2로 받아들이는 메소드를 만들 수 있는지 알고 싶습니다.

스프링의 다양한 직조 / 강제 / AOP 기술자가이를 가능하게해야한다고 생각하지만, 어떻게해야할지 모르겠다.

이것이 일어날 수있는 방법이 있습니까?

해결법

  1. ==============================

    1.예, 동적 프록시 또는 바이트 코드 재 작성을 사용합니다. 그러나 나에게 그것은 당신이 어댑터 패턴을 찾는 것처럼 보인다.

    예, 동적 프록시 또는 바이트 코드 재 작성을 사용합니다. 그러나 나에게 그것은 당신이 어댑터 패턴을 찾는 것처럼 보인다.

  2. ==============================

    2.객체 자체가 인터페이스를 구현하도록 만들 수는 없지만 Proxy와 같은 것을 사용하여 인터페이스를 구현하는 객체를 만들고 리플렉션을 사용하여 원래 객체의 적절한 멤버를 호출 할 수 있습니다.

    객체 자체가 인터페이스를 구현하도록 만들 수는 없지만 Proxy와 같은 것을 사용하여 인터페이스를 구현하는 객체를 만들고 리플렉션을 사용하여 원래 객체의 적절한 멤버를 호출 할 수 있습니다.

    물론, 하나의 인터페이스 유형과 하나의 구체적인 유형 인 경우 프록시를 사용하지 않고 이러한 래퍼를 쉽게 작성할 수 있습니다.

    public class BarWrapper implements Foo
    {
        private final Bar bar;
    
        public BarWrapper(Bar bar)
        {
            this.bar = bar;
        }
    
        public int someMethodInFoo()
        {
            return bar.someMethodInFoo();
        }
    
        // etc
    }
    
  3. ==============================

    3.이것은 어댑터로 해결할 수 있어야합니다. 인터페이스를 구현하고 실제 객체에 위임하는 다른 클래스를 정의하십시오.

    이것은 어댑터로 해결할 수 있어야합니다. 인터페이스를 구현하고 실제 객체에 위임하는 다른 클래스를 정의하십시오.

    class YourAdapter implements YourInterface {
    
        private final YourClass realObject;
    
        public YourAdapter(YourClass realObject) {
            this.realObject = realObject;
        }
    
        @Override
        public methodFromInterface() {
            // you said the class has the same method signatures although it doesn't
            // implement the interface, so this should work fine:
            realObject.methodFromInterface();
        }
    
        // .......
    
    }
    

    이제 YourInterface와 YourClass 유형의 객체를 기대하는 메소드가 제공됩니다.

    void someMethod(YourInterface param) {}
    
    void test() {
        YourClass object = getFromSomewhere();
        someMethod( YourAdapter(object) );
    }
    
  4. ==============================

    4.클래스의 바이트 코드를 수정하거나 래퍼 / 프록시 클래스를 작성하여 Javassist로 원하는 것을 할 수 있습니다.

    클래스의 바이트 코드를 수정하거나 래퍼 / 프록시 클래스를 작성하여 Javassist로 원하는 것을 할 수 있습니다.

  5. ==============================

    5.기본적으로 두 가지 방법이 있습니다.

    기본적으로 두 가지 방법이 있습니다.

    a) 인터페이스를 구현하고 객체에 위임하는 객체 주위에 데코레이터를 작성합니다 (프록시를 사용하거나 간단한 어댑터 클래스를 작성하여 수행 할 수 있음)

    b) 바이트 코드를 변경합니다. Spring AOP는 그렇게하기에는 강력하지 않지만, AspectJ 컴파일러는 그렇다. 그것은 하나의 라이너입니다.

    declare parents: YourClass implements YourInterface;
    

    클래스 소스에 액세스 할 수 없으므로로드 시간 짜기를 사용하거나 라이브러리 항아리를 짜야합니다. 이 모든 것은 Ramnivas Laddad의 AspectJ in Action에서 잘 설명되어있다.

  6. from https://stackoverflow.com/questions/5196941/can-you-force-a-java-object-into-implementing-an-interface-at-runtime by cc-by-sa and MIT license