Spring ApplicationContext

Status
Nicht offen für weitere Antworten.

MQue

Top Contributor
Hallo,

ich verwende in meiner Web- Application Spring und benötige den ApplicationContext in mehreren Klassen, um über die XML- Datei auf andere Objekte zuzugreifen.

Meine Frage wäre jetzt, ist es OK, mehrere Instanzen von ClassPathXmlApplicationContext zu haben (in diesem Fall 2 (unten))? Ich bekomme nämlich eine Exception (unten) und vermute mal, das diese 2 Instanzen zuviel sind, sprich das man nur eine Instanz von ClassPathXmlApplicationContext habe darf??
lg

in Klasse 1 und Klasse 2 steht genau dieser Code, also ich erzeuge 2 Instanzen von
ClassPathXmlApplicationContext
Code:
final ApplicationContext ctx = new ClassPathXmlApplicationContext(PATH);     
startDatabase = (StartDatabase)ctx.getBean("startdatabase");

Code:
INFO: Illegal access: this web application instance has been stopped already.  Could not load org.springframework.expression.spel.antlr.SpringExpressionsParserExtender.  
The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException

        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273)
Exception in thread "Thread-1" java.lang.NoClassDefFoundError: org/springframework/expression/spel/antlr/SpringExpressionsParserExtender
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
        at org.springframework.expression.spel.antlr.SpelAntlrExpressionParser.<init>(SpelAntlrExpressionParser.java:51)
        at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
 
M

maki

Gast
Mit deinem Design stimmt imho etwas grundlegendes nicht.

getBean() sollte man eigentlich nie aufrufen, höchstens in Unittests.
Dass du damit dann auch noch mehrere ApplicationContexts erzeugst ist ein weiterer Fehler.
 

MQue

Top Contributor
Mit deinem Design stimmt imho etwas grundlegendes nicht.

getBean() sollte man eigentlich nie aufrufen, höchstens in Unittests.
Dass du damit dann auch noch mehrere ApplicationContexts erzeugst ist ein weiterer Fehler.

Versteh ich jetzt nicht (das mit getBean). In diesem Tut. wurde es aber so gemacht??

http://www.java-forum.org/blogs/tfa/27-how-engl-thread-opener-themeneroeffner-dependency-injection-mit-spring.html

Wie kann ich es dann am Besten machen
 

byte

Top Contributor
Du hast das Prinzip von DI noch nicht verstanden. Wenn Du in einer Klasse ein Objekt aus dem ApplicationContext brauchst, dann brauchst Du dafür nicht auf den ApplicationContext zugreifen. Du verdrahtest einfach das Objekt als Member und Spring macht dann den Rest.

Am einfachsten geht das mit Annotations:

Java:
public class Foo {
  @Autowired
  private Bar bar;

  ...
}
 

byte

Top Contributor
Versteh ich jetzt nicht (das mit getBean). In diesem Tut. wurde es aber so gemacht??

http://www.java-forum.org/blogs/tfa/27-how-engl-thread-opener-themeneroeffner-dependency-injection-mit-spring.html

Wie kann ich es dann am Besten machen

Das ist ein simpler Test mit einer Main-Methode. In der Main Methode wird der ApplicationContext geladen.

Du hast aber keine Main Methode sondern eine Webanwendung. In Webanwendungen wird kein ClasspathApplicationContext benutzt sondern ein WebApplicationContext. Dieser wird vom Container geladen, wenn die Webanwendung deployed bzw. gestartet wird.

Wenn Du wirklich Zugriff auf den ApplicationContext brauchst (was in den meisten Fällen aber NICHT nötig ist), dann kannst Du einfach das Interface ApplicationContextAware implementieren und der AppContext wird dann von Spring injiziert.
 
M

maki

Gast
Versteh ich jetzt nicht (das mit getBean). In diesem Tut. wurde es aber so gemacht??

....

Wie kann ich es dann am Besten machen
tfa hat in seinem Blog ein Bespiel erstellt, das auch eine main beinhaltet, zu Demostrationszwecken. Ein einziges mal kann man den Kontext so schon erstellen, und da dann getBean aufrufen, ist aber eher etwas für Demonstrationszwecke und soll die Grundlagen von Spring und DI erklären.

Die orig. Spring Dopku enthält dann noch viel mehr Bespiele, solltest du unbedingt auch mal lesen ;)
 

MQue

Top Contributor
Gibts irgendwo eine "main"- Applikation in der nur @Autowired verwendet wird?
Ich hab jetzt meine Applikation (NICHT meine Webapplikation) nur auf @Autowired umgeändert und bekomme glatt eine NPE:

Meine Klasse:

Java:
public final class StartService {

    @Autowired
    @Qualifier("startdatabase")
    private StartDatabase startdatabase;
    private static final String PATH;

    static {
        PATH = "file:///C:/conf/applicationContext.xml";
        }

    public StartService() {
        final ApplicationContext ctx = new ClassPathXmlApplicationContext(PATH);
        }

    private void start() {
         /* start database (hibernate) */
        System.out.println("Das ist startdatabase: " + startdatabase);
        startdatabase.insertVariables();
        /* start tcpconnection */
        //final StartTcp startTcp = (StartTcp)ctx.getBean("starttcp");
        //startTcp.startTCPConnection();
        }

    public static void main(String[] args) {
        final StartService startService = new StartService();
        startService.start();
        }
}

Code:
<beans .... >
	<context:annotation-config />                                               <!-- Beans über Annotationen konfigurieren -->
		<bean id="startdatabase"       class="net.hibernate.StartDatabase"       scope="singleton"/>
		<bean id="starttcp"            class="net.tcpinterface.StartTcp"         scope="singleton" >
	        <constructor-arg>
	            <ref local="startdatabase"/>
	        </constructor-arg>
	    </bean>
		<bean id="xmlElementProvider"  class="net.xmlreader.XMLElementProvider"  scope="singleton"/>
	    <bean id="reader"              class="net.xmlreader.ReadController"      scope="singleton"/>	    	    
</beans>
 
Zuletzt bearbeitet:

MQue

Top Contributor
Moin,

ich muss nochmal fragen, warum das unten mit

@Autowired
@Qualifier("writer")
private IWriteController wc;

nicht geht (das ist das Beispiel vom Blog)

Java:
import config.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Main {

    @Autowired
    @Qualifier("writer")
    private IWriteController wc;
    private static final String PATH;

    static {
        PATH = "file:///" + System.getProperty("user.dir") + "/conf/applicationContext.xml";
        }

    public Main() {
        final ApplicationContext ctx = new ClassPathXmlApplicationContext(PATH);        // Spring initialisieren und Kontext laden, applicationContext.xml ist die oben angegebene Konfigurationsdatei.
        //final IWriteController wc = (IWriteController)ctx.getBean("writer");              // Über das Context-Objekt können die konfigurierten Beans über ihre Namen abgerufen werden.
        final IReadController rc = (IReadController)ctx.getBean("reader");
        wc.doConfig();
        rc.printConfig();        
        }

    public void setWriter(final WriteController wc) {
        this.wc = wc;
        }

    public static void main(String... args) {
        new Main();
        }
}
 

MQue

Top Contributor
Der Code macht überhaupt keinen Sinn. Lies erstmal die Doku.

Bin dabei, "Spring in Action" zu lesen, und bin da auf Seite 86 (von 700 :-( ), mir ist Grundsätzlich auch klar, wies funktioniert und was man alles in der XML- Datei einstellen kann (autowire, abstract, set, list, value, ref usw.), mit ist jetzt aber nicht klar, warum das nicht funktioniert bzw. warum das keinen Sinn macht.

Was ich bis jetzt verstehe ist folgendes:
Ich lade mit ApplicationContext ctx = new ClassPathXmlApplicationContext(PATH); den Kontext, ab da müsste das SpringFramework aktiv?/ bereit sein um dann z.B.: @Autowired auszuführen (so mal meine einfache Vorstellung).

Bin ich da am Holzweg, wie könnte man das von oben realisieren, sodass ich nur einmal ApplicationContext bzw. WebApplicationContext brauche?
 

byte

Top Contributor
Bin dabei, "Spring in Action" zu lesen, und bin da auf Seite 86 (von 700 :-( ), mir ist Grundsätzlich auch klar, wies funktioniert und was man alles in der XML- Datei einstellen kann (autowire, abstract, set, list, value, ref usw.), mit ist jetzt aber nicht klar, warum das nicht funktioniert bzw. warum das keinen Sinn macht.

Wenn Du ein Objekt per new Operator erzeugst, dann funktioniert @Autowire natürlich nicht. :autsch:

@Autowire funktioniert natürlich nur für Spring Beans, also Objekte, die Spring selbst erzeugt und die man über den ApplicationContext abruft. Wichtig ist, dass Du den ApplicationContext nur ein einziges Mal erzeugst und nicht mehrfach. In WebAnwendungen erzeugt man ihn gar nicht, das passiert über den Container.
 

MQue

Top Contributor
zwei Fragen hätte ich noch:

Wenn Du ein Objekt per new Operator erzeugst, dann funktioniert @Autowire natürlich nicht. :autsch:

ich vermute mal, Du sprichtst da obiges Beispiel von mir an, meinst Du da das new Main()? und wie kann ich das machen, das es so (ähnlich) funktioniert?

Wichtig ist, dass Du den ApplicationContext nur ein einziges Mal erzeugst und nicht mehrfach. In WebAnwendungen erzeugt man ihn gar nicht, das passiert über den Container.

Muss ich dem Container (bei mir tomcat) was konfigurieren (in der web.xml) oder reicht es wenn ich die jar's im WEB-INF/lib habe und ins Projekt hinzugefügt habe (ich vermute mal ich muss was in den dd hineinschrieben)?

Vielen Dank!
 

byte

Top Contributor
Du musst etwas in die web.xml schreiben, damit der WebApplicationContext beim Starten der WebAnwendung hochgefahren wird.

Wie das genau geht, kannst Du alles in der sehr guten Spring Doku lesen. Ist mir jetzt zuviel Arbeit, das hier alles im Detail zu erläutern.

PS: Learning by asking ist nicht umbedingt die beste Art voranzukommen...
 

byte

Top Contributor
Kannst ja gerne konkrete Fragen stellen, aber bei manchen Deiner Fragen sieht man einfach, dass Du die Basics noch nicht beherrscht. Und ein bißchen Eigeninitiative ist schon gefordert.
 

MQue

Top Contributor
Kannst ja gerne konkrete Fragen stellen, aber bei manchen Deiner Fragen sieht man einfach, dass Du die Basics noch nicht beherrscht. Und ein bißchen Eigeninitiative ist schon gefordert.

Da magst Du recht haben, es ist am Anfang halt schwierig, wenn man bei einem so großen Framework von null anfangen muss. Leider kann ich in der Firma auch keinen fragen, es hat keiner einen Ahnung.
Ich hoffe meine Lernkurve steigt schnelle (hab nächste Woche Urlaub)

Könntest Du mir noch einen Tipp geben, wo ich das finde, was ich in den dd schreiben muss? ist es das -> PartIII.The Web
 
Zuletzt bearbeitet:

Noctarius

Top Contributor
Prinzipiell hat Spring eine sehr steile Lernkurve. Hast du die Grundbasics verstanden, kommt der Rest beim lesen der Soku oder API fast von alleine.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Spring applicationContext Application Tier 3
M Spring DM: Problem mit Tomcat als OSGI-Service Application Tier 1
G Spring/Hibernate exception Application Tier 17
S Spring: Klassen in anderer "Anmelden" Application Tier 16
RaoulDuke Spring - Bugfixes in 2.5.x Application Tier 4
G Spring rollbackFor Application Tier 8
MQue Spring Security Form Application Tier 3
D Spring konfigurieren mit XML, Annotionen oder Java? Application Tier 2
MQue Spring in Zukunft Application Tier 5
I Passwort verschlüsseln in DB mit Spring Application Tier 5
MQue Spring https Application Tier 7
I Security bei Spring? Application Tier 31
MQue Spring beans Application Tier 10
I Wieviel Projekte bei Spring? Webprojekt Application Tier 2
G Transaktionen Spring Application Tier 58
Y Spring und Hibernate Application Tier 2
K Spring DI existierendes Objekt übergeben Application Tier 2
MQue Spring Autowired Application Tier 7
MQue Spring Proxys Application Tier 2
D Problem beim Testen von einer Spring-Anwendung Application Tier 8
MQue Spring BeanFactoryPostProcessor Application Tier 3
S Spring util:list in eine andere importieren Application Tier 15
MQue Einsatz von Spring Application Tier 13
M Konfiguration WebApp/Spring Host-abhängig Application Tier 5
E Migration altes Framework (SOFIA) auf Spring Application Tier 3
D Automatische Typkonvertierung in Spring Application Tier 5
D Spring und Hbernate konfigurieren bzw. verschalten Application Tier 5
A Spring: JSP nimmt style.css nicht an Application Tier 3
G Spring Security Frage fuer Fortgeschrittene Application Tier 2
Y Spring + MyFaces - Exception bei Serverstart Application Tier 1
Y Maven MyFaces Hibernate Spring - Projekt Application Tier 1
byte [Spring] Referenced Bean not found Application Tier 2
M Spring - Leichtgewichtiger als JBoss? Application Tier 4
D Spring: setter injection von statischer Methode? Application Tier 1
reibi Spring Beans - Grundsatzfrage Application Tier 3
thE_29 Spring und XFire Frage Application Tier 3
H spring Application Tier 2
R Spring und Hibernate3 - CGLib Enhancement failed Application Tier 2
S Spring 2.0 Tutorial gesucht Application Tier 2
M JBoss Seam - Spring Application Tier 11
G [Spring+JSF]: VariableResolver und Scopes? Application Tier 1
L Spring Kann die applicationContext.xml nicht finden Application Tier 1
C ApplicationContext mehrfach laden? Application Tier 3

Ähnliche Java Themen

Neue Themen


Oben