2016-03-30 13 views
0

Ich erstelle ein neues Plugin mit CustomService, das einen vorhandenen Dienst von einem vorhandenen Plugin ersetzen soll. Nach dem Muster, das in benutzerdefinierten Sicherheitsimplementierungen gefunden wurde und here angezeigt wird, habe ich die Konfiguration zu resources.groovy, oldService (path.to.new.CustomService) hinzugefügt. Ich habe auch versucht, alle injizierten Klassen in die Schließung für diesen Dienst hinzuzufügen. (Tatsächliche Dienstnamen sind RegistrationPersonRegistrationCompositeService und NewRegistrationPersonRegistrationCompositeService im Codeblock)Überschreibe einen Dienst in Grails mit der Spring Bean-Deklaration

Ich möchte nicht, dass der ursprüngliche Anwendungscode einen Verweis auf das neue Plugin enthält. BuildConfig auf Anwendungsebene erfordert jedoch den Eintrag plugin.location. Meine resource.groovy Mods sind im neuen Plugin. Ich hatte keinen Erfolg in diesem Bestreben. Ändere ich die falschen resources.groovy? Wenn diese Änderung im ursprünglichen Anwendungscode erforderlich ist, habe ich die Möglichkeit verloren, den ursprünglichen Code unverändert zu lassen. Ich erweitere weder den ursprünglichen Service noch verwende Override Annotation. Meine Absicht ist, den Service (Frühlingsbohne) beim Start zu ersetzen. Das neue Plugin hat eine Abhängigkeit vom alten Plugin, um die Reihenfolge der Operationen beim Laden dieser Klassen zu verwalten.

Ist es wichtig, dass der alte Dienst zuvor in eine Steuerung eingespeist wurde? Dies würde erfordern, dass ich den Controller im neuen Plugin auf die gleiche Weise überschreiben und den richtigen Dienst für das gewünschte Verhalten einspeisen würde?

Ich habe eine Dokumentation gefunden, die zeigt, dass in einem Plugin resources.groovy ignoriert wird. Auch der Aufbau der resources.groovy in einen Krieg ist problematisch. Ich habe keine Lösung gefunden. Ich bekomme keinen Fehler, den ich teilen kann, nur dass das gewünschte Verhalten fehlt; Der ursprüngliche Dienst bearbeitet die Anfragen.

//was resource.groovy - now renamed to serviceOverRide.groovy - still located in \grails-app\conf\spring of plugin 
//tried this with and without the BeanBuilder. Theory: I'm missing the autowire somehow 
import org.springframework.context.ApplicationContext 
import grails.spring.BeanBuilder 

def bb = new BeanBuilder() 

bb.beans { 
    registrationPersonRegistrationCompositeService(path.to.services.registration.NewRegistrationPersonRegistrationCompositeService) { bean -> 
     bean.autowire = true 
     registrationRestrictionCompositeService = ref("registrationRestrictionCompositeService") 
     registrationPersonTermVerificationService = ref("registrationPersonTermVerificationService") 
    } 
    classRegistrationController(path.to.services.registration.ClassRegistrationController) { bean -> 
     bean.autowire = true 
     selfServiceLookupService = ref("selfServiceLookupService") 
     registrationPersonRegistrationCompositeService = ref("registrationPersonRegistrationCompositeService") 
    } 
} 
ApplicationContext appContext = bb.createApplicationContext() 

Zusätzliche Informationen: Die folgenden Zeilen zum PluginGrailsPlugin.groovy hinzugefügt. Der ursprüngliche Service ist der Umgang mit noch diese Anforderungen

def dependsOn = ['appPersonRegistration': '1.0.20 > *'] 
List loadAfter = ['appPersonRegistration'] 

def doWithSpring = { 
    registrationPersonCourseRegistrationCompositeService(path.to.new.registration.TccRegistrationPersonCourseRegistrationCompositeService) 
} 

def doWithApplicationContext = { applicationContext -> 
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL) 
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory() 
    beanFactory.registerBeanDefinition("registrationPersonCourseRegistrationCompositeService", BeanDefinitionBuilder.rootBeanDefinition(TccRegistrationPersonCourseRegistrationCompositeService.class.getName()).getBeanDefinition()) 
} 

Antwort

1

ich sehr empfehlen Sie den Abschnitt der Dokumentation auf Plugins lesen. Der Grund, warum ich das empfehlen, weil Plugins:

  • Geben Sie keine, oder ein Mittel, durch doWithSpring Verwendung von resources.groovy
  • machen Geben Sie die Feder Anwendung zu bewirken

die Informationen in der Dokumentation Nach Sie sollten kein Problem haben, den Dienst im Anwendungskontext zu überschreiben.

Sie müssen Ihre Änderungen in den Anwendungskontext implementieren doWithSpring Dies ist der Schlüssel zur Lösung Ihrer Probleme.

+0

doWithAplicationContext ist ein Teil dieser Lösung. Die Bean kann immer noch nicht geladen werden, aber die Ursache scheint darin zu liegen, dass die Bean selbst von anderen registrierten/injizierten Beans abhängig ist. Siehe Beispiel mit der Anweisung resources.groovy/bohnen und einem Abschluss, um die entsprechenden Beans mit dieser Deklaration zu verknüpfen: http : //stackoverflow.com/questions/7132679/override-method-of-grails-plugin-bean/7135267#7135267 für die SpringSecurity-Bean und ihre injizierten Beans. Meine Herausforderung besteht darin, das Gleiche mit BeanFactory und doWithApplicationContext zu tun. Haben Sie dieses Problem oder diese Auflösung mit verschachtelten Beans gesehen? – Duane5000

0

In dieser Implementierung hatte ich eine Dienstmethode in einem Dienst, für den ich versuchte, eine Überschreibung bereitzustellen. Problem ist, dass der Aspekt als Proxy arbeitet und eine Methode überschreiben muss, die direkt von einer anderen Klasse aufgerufen wird. In meinem classRegistrationController habe ich service processRegistration() aufgerufen, was wiederum applyRules() aufgerufen hat. Beispielhafte Methodennamen, die verwendet werden. Da der Dienst ein eigenes Dienstprogramm aufgerufen hat, gab es keine Möglichkeit für den Proxy/Wrapper, den Aufruf von applyRules() zu umgehen. Sobald dies entdeckt wurde, habe ich den Code auf diese Weise überarbeitet: Controller ruft processRegistration auf, wie es immer war. Nach der Rückkehr wird ein weiterer Aufruf an den Dienst, processLocalRules(), getätigt. Die neue Methode ist ein leerer Platzhalter, der von der benutzerdefinierten Logik des Clients überschrieben werden soll. Das Plugin mit Aspect funktioniert jetzt mit resources.groovy.Ich bevorzuge das doWithSpring, wie Joshua aus diesem Grund erklärte: meine Absicht, das Plugin ohne Modifikation der ursprünglichen App-Config funktionieren zu lassen; Andernfalls ist resource.groovy ein gültiger Ansatz. Die Antwort von Joshua aufheben, da es die Anforderung erfüllt und sauberer ist. Vielen Dank!

Verwandte Themen