2013-07-16 7 views
5

W bardzo dużej, starej aplikacji mam interfejsy i klasy, które wykonują , a nie implementują te interfejsy.Wiosna: Deleguj na niestandardowe opakowanie pośredniczące dla wtrysku interfejsu

Interfejsy są generowane w oparciu o klasę, więc sygnatury są takie same (z wyjątkiem tego, że interfejs dodaje inny wyjątek na wierzchu), a nazwy są podobne (więc można łatwo znaleźć nazwę klasy z nazwy interfejsu).

Aby uzyskać implementację interfejsu, wykonujemy garść protokołów przetwarzania i rejestrowania połączeń, ale zasadniczo należy użyć java.lang.reflect.Proxy do delegowania na zajęcia. Uproszczone wygląda to tak:

// This will create a proxy and invoke handler that calls HelloWorld.doSomething 
HelloWorldInterface i = MyProxyUtil.getInstance(HelloWorldInterface.class); 
i.doSomething(); 

public interface HelloWorldInterface { 
    public void doSomething() throws Exception; 
} 

public class HelloWorld { 
    public void doSomething() { 
    //something 
    } 
} 

Czy to możliwe z przetwarzaniem Wiosna adnotacji, aby rodzajowo @Autowire wszystkich dziedzinach typu *Interface i wykorzystania sprężyny MyProxyUtil.getInstance(*Interface.class) wstrzyknąć realizację?

Takie,

@Autowire HelloWorldInterface a; 

HelloWorldInterface b = MyProxyUtil.getInstance(HelloWorldInterface.class); 

@Autowire AnotherInterface c; 

AnotherInterface d = MyProxyUtil.getInstance(AnotherInterface.class); 


a == b 
c == d 

Odpowiedz

9

Tak, musisz zaimplementować AutowireCandidateResolver.

Na przykład:

public class ProxyAutowiredCandidateResolver extends SimpleAutowireCandidateResolver { 

    @Override 
    public Object getSuggestedValue(DependencyDescriptor descriptor) { 
     String dependencyClassName = descriptor.getDependencyType().getSimpleName(); 
     if (dependencyClassName.endsWith("Interface")) { 
      return MyProxyUtil.getInstance(descriptor.getDependencyType()); 
     } 

     return super.getSuggestedValue(descriptor); 
    } 

} 

można użyć BeanFactoryPostProcessor skonfigurować go w kontekście aplikacji:

public class AutowireCandidateResolverConfigurer implements BeanFactoryPostProcessor { 

    private AutowireCandidateResolver autowireCandidateResolver; 

    public void postProcessBeanFactory(
      ConfigurableListableBeanFactory beanFactory) throws BeansException { 
     DefaultListableBeanFactory bf = (DefaultListableBeanFactory) beanFactory; 
     bf.setAutowireCandidateResolver(autowireCandidateResolver); 


    } 

    public AutowireCandidateResolver getAutowireCandidateResolver() { 
     return autowireCandidateResolver; 
    } 

    public void setAutowireCandidateResolver(

      AutowireCandidateResolver autowireCandidateResolver) { 
     this.autowireCandidateResolver = autowireCandidateResolver; 
    } 

} 

<bean id="autowireCandidateResolverConfigurer" class="AutowireCandidateResolverConfigurer"> 
     <property name="autowireCandidateResolver"> 
      <bean class="ProxyAutowiredCandidateResolver" /> 
     </property> 
</bean> 
+0

Przepraszam, mam trudności z ustaleniem, jak to skonfigurować? Co powinienem dodać do mojego pliku applicationContext.xml? –

+0

@casenelson można użyć 'BeanFactoryPostprocessor' do skonfigurowania' AutowireCandidateResolver' –

+0

Występuje problem z wtryskiem Środowiska z rozwiązaniem -> https: // github.pl/mariuszs/env-is-null – MariuszS

1

Jeśli czytam to poprawnie, powinieneś być w stanie określić je w JavaConfig @Configuration uwagami klasy, a następnie wykorzystać je w innym miejscu.

Od docs (Spring):

@Configuration 
public class AppConfig { 
    @Bean 
    public MyService myService() { 
     return new MyServiceImpl(); 
    } 
} 

Można zrobić coś podobnego:

@Configuration 
public class InterfaceConfig { 
    @Bean 
    public HelloWorldInterface helloWorldInterface() { 
     return MyProxyUtil.getInstance(HelloWorldInterface.class); 
    } 
} 

W tym momencie, Wiosna mogliby wykorzystać tę definicję ilekroć że fasola była potrzebna.

Musisz jakoś połączyć w klasie @Configuration (skanowanie ścieżek klas, programowo itp.), Ale to zależy od tego, jak konfigurujesz kontekst aplikacji.

Myślę, że to powinno zadziałać. Używałem JavaConfig całkiem sporo, ale nigdy tak nie lubię. Ale wydaje się rozsądne.

+0

To naprawdę nie jest praktyczne dla mnie zdefiniować każdy z tych ziaren w config (są setki). Zamiast tego, szukam sposobu na rozwiązanie wszystkich interfejsów, których nazwa kończy się na interfejsie MyProxyUtil. –

+0

Nie złapałem tej części. Jeśli to wszystko jest starsze, nie byłoby trudno napisać skrypt, który wygenerowałby kod jednorazowo. Odpowiedź Jose brzmi interesująco, nie byłem tego zaznajomiony. Czy serwery proxy są już zarządzane w trybie wiosennym? Czy próbujesz zrobić z nimi cokolwiek, co by wymagało, aby były wiosenne, jeśli nie? – Jafoy

Powiązane problemy