Jul 06 2008

Access the Spring-ApplicationContext from everywhere in your Application

Published by Siegfried Bolz at 9:03 pm under Java, Spring



In this blog i will show you a short hint how you can access your Spring-ApplicationContext from everywhere in your Application.

Imagine you have an application (e.g. a web or swing-application) which you now want to be Spring-enabled. Ok you add the Spring libraries and the Configuration-file and create your Spring-beans. But there are still some old class-files which you can’t use in this way. These files still need access to the Spring-Honeypot where all the goodies exists and you don’t want to redesign your application.

First create the class “ApplicationContextProvider“. This class implements the ApplicationContextAware. A bean which implements the ApplicationContextAware-interface and is deployed into the context, will be called back on creation of the bean, using the interface’s setApplicationContext(…) method, and provided with a reference to the context, which may be stored for later interaction with the context.

ApplicationContextProvider.java

package context;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * This class provides an application-wide access to the
 * Spring ApplicationContext! The ApplicationContext is
 * injected in a static method of the class "AppContext".
 *
 * Use AppContext.getApplicationContext() to get access
 * to all Spring Beans.
 *
 * @author Siegfried Bolz
 */
public class ApplicationContextProvider implements ApplicationContextAware {

    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        // Wiring the ApplicationContext into a static method
        AppContext.setApplicationContext(ctx);
    }
} // .EOF


This bean must be initialized in the Spring-Configuration file:

applicationContext.xml

<bean id="contextApplicationContextProvider" class="context.ApplicationContextProvider"></bean>



The key for success is located in the in the method “setApplicationContext(…)“, here we are wiring the injected ApplicationContext into the static method “public static void setApplicationContext(ApplicationContext applicationContext) of the class “AppContext“:

AppContext.java

package context;

import org.springframework.context.ApplicationContext;

/**
 * This class provides application-wide access to the Spring ApplicationContext.
 * The ApplicationContext is injected by the class "ApplicationContextProvider".
 *
 * @author Siegfried Bolz
 */
public class AppContext {

    private static ApplicationContext ctx;

    /**
     * Injected from the class "ApplicationContextProvider" which is automatically
     * loaded during Spring-Initialization.
     */
    public static void setApplicationContext(ApplicationContext applicationContext) {
        ctx = applicationContext;
    }

    /**
     * Get access to the Spring ApplicationContext from everywhere in your Application.
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
} // .EOF


Now you have access from all class-files to the Spring-ApplicationContext in your application, if you call the static method:

Poorfile.java

ApplicationContext ctx = AppContext.getApplicationContext();
Honeypotbean honey = (HoneyPotBean) ctx.getBean("honey");


Do you have any improvements? Please drop a comment below.

Technorati Tags: , ,


48 Responses to “Access the Spring-ApplicationContext from everywhere in your Application”

  1. Tomas Jurmanon 14 Jul 2008 at 8:01 pm

    Hi Siegfried Bolz

    Thank for you article about Spring applicationContex. Today I use your classes it in me application. It work perfect.

    See you
    Tomas Jurman
    Czech Republic

  2. Kalon 28 Jul 2008 at 7:44 am

    It’s not really necessary to create a separate AppContext class, right? Why not let the ApplicationContextProvider have a static field to hold the application context?

  3. Siegfried Bolzon 28 Jul 2008 at 10:12 pm

    Hello Kal,
    yes you can use a static field in the ApplicationContextProvider, my way was to use a separate class.

  4. Prasannaon 10 Sep 2008 at 6:31 am

    Very neat program. I was looking for something like this to be injected from a webservice end-point. Works very well. Thanks

  5. Longon 19 Sep 2008 at 10:40 am

    Can I ask you one question.

    - The application context can be changed every where in the application ?

    I have problems in connecting to DB. I can not find any way to change hibernate.default_schema property in my application.

    Can you help me ?

  6. Ratnaon 07 Nov 2008 at 6:46 pm

    Hello Bolz,
    Thanks alot for this useful blog. I was trying to get currrent apllication context using many approches,but I could nto succed. Getting applucation context was very import for some complex requirements. Your code solved my issue of application context.

    Thanks,
    Ratna

  7. Juanmaon 21 Nov 2008 at 11:44 am

    Menudo crack !!!!!!!

    thanks a lot

    Juanma
    Spain

  8. Valentynaon 02 Dec 2008 at 8:14 am

    Thank you so much!!!

  9. Alion 24 Dec 2008 at 12:31 pm

    hi
    i wanna ask u what do u mean by:

    Honeypotbean honey = (HoneyPotBean) ctx.getBean(”honey”);
    ????

    thanks

  10. Siegfried Bolzon 24 Dec 2008 at 10:51 pm

    Hello Ali,
    this is just an information how you can get access to all beans stored in the Spring-ApplicationContext (the Honeypot).

  11. thiago dinizon 12 Jan 2009 at 6:02 pm

    Hello Bolz,
    i am getting a problem with your code, the method AppContext.getApplicationContext() is returning null, do you have any ideia?

    thanks

  12. Marcia Piccioneon 07 Feb 2009 at 5:38 am

    This solution keeps recreating the beans in the application context over and over again. Obviously a big problem for connection pools. Is there a way to access the application context without creating a new one?

  13. Siegfried Bolzon 07 Feb 2009 at 8:13 pm

    Marcia, the Context will be only once created on the initialization of the application (done by the ApplicationContextAware). If you access the Context, it is always the same and not a new one.

  14. Mauricioon 29 Apr 2009 at 7:31 pm

    Thanks a lot!!!
    It’s working for my application, and it is very usefull.
    What other kind of magik can we do with the ApplicationContextAware?? :>
    if any have an awnser to my question, please post it.

  15. walsenon 09 Jun 2009 at 9:01 am

    Thanks a lot too.
    Very usefull and nice code.

  16. Pankajon 17 Jun 2009 at 8:28 pm

    Wonderful post. I didn’t knew about ApplicationContextAware. Good work.

  17. Bretton 22 Jul 2009 at 7:03 am

    Thanks Siegfried, A Great post;

    A good solution for those who are forced to use someone elses container.

    Cheers
    Brett

  18. Vinayaon 06 Aug 2009 at 9:34 pm

    Hi,

    I was using,

    ctx=new ClassPathXmlApplicationContext(”WEB-INF/applicationContext.xml”);
    In this case, it used to create all the beans again. I was able to see that in the log which was as follows…

    [code]
    NFO [org.springframework.context.support.ClassPathXmlApplicationContext] Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4605c7: display name [org.springframework.context.support.ClassPathXmlApplicationContext@4605c7]; startup date [Thu Aug 06 16:31:47 EDT 2009]; root of context hierarchy
    2009-08-06 16:31:47,779 [,] INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] Loading XML bean definitions from class path resource [WEB-INF/applicationContext.xml]
    2009-08-06 16:31:48,295 [,] INFO [org.springframework.context.support.ClassPathXmlApplicationContext] Bean factory for application context [org.springframework.context.support.ClassPathXmlApplicationContext@4605c7]: org.springframework.beans.factory.support.DefaultListableBeanFactory@179b905
    2009-08-06 16:31:48,373 [,] INFO [org.springframework.beans.factory.config.PropertyPlaceholderConfigurer] Loading properties file from class path resource [WEB-INF/classes/trade.properties]
    2009-08-06 16:31:48,483 [,] INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@179b905: defining beans [propertyConfigurer,tradeConfig,transactionManager,contextApplicationContextProvider,fileUploadForm,multiPartSearch,mPContainer,applicationBean,screenReturnPath,BaseListBean,dataTable,voaDataTable,noemDemandTable,oemDemandTable,noemReqLineTable,oemReqLineTable,noemSupplyTable,oemSupplyTable,quoteTable,noemQuoteTable,oemQuoteTable,poHistoryTable,poHistorySngTable,poHistoryAMTable,noemPoHistoryTable,oemPoHistoryTable,noemsoHistoryTable,oemsoHistoryTable,stockTable,searchReqTable,supplyHistTable,supplyNoteTable,demandHistTable,demandNoteTable,myBuyerQuotes,otherBuyerQuotes,custShipToAdd,custBillToAdd,acctSearchTable2,mfrSearchTable2,cnoSearchTable,stocklocationTable,stockNoteTable,arsSearch1,arsSearch2,arsSearch3,poSearch,vendorSearch,soSearchTable,userApprovalLocationsBean,uplLEntryHandler,secRoleHandler,secRoleAdmin,webAppHandler,adminProfileHandler,userLoginHandler,workGroupAdmin,adminWgHandler,SequenceBean,tradeSessionBean,menuNavigation,userBean,tradeAuthenticationController,loginBean,tradeLoginUser,tradeRules,tradeProfiles,tradeProfilesHandler,userAdminBean,userLoginAdminBean,addEditUserLogin,stockItemsVwHandler,multiviewSearch,ddlBean,clearCache,accountVwBean,accountSearchHandler,customerSearchHandler,customerAddressSearchHandler,contactDetailsVwBean,contactDetailsVwHandler,buyerQuoteLinesHandler,otherQuoteLinesHandler,addQuote,buyerQuotesDetails,editQuote,searchBuyerReqReqLinesHandler,viewQuote,viewReqLine,viewBuyerCustomerRequirement,customerReqLinesBean,customerRequirementsBean,upLoadReqLines,uploadSig,custReqLineHistHandler,requirementBuyersBean,requirementBuyersHandler,buyerQuotesBean,quoteLinesHandler,quoteVwBeanHandler,addReqLine,closeRequirement,createCustomerRequirement,customerReqLinesHandler,editCustomerRequirement,editReqLine,searchReqReqLinesHandler,quoteAcceptance,sellerQuoteDetail,arsSupplyHandler,searchArsHandler,arsDemandHandler,stockHandler,controlNoSearchHandler,demandHistVwBean,demandHistVwHandler,demandHistoryDetail,demandNotesBean,demandNotesHandler,demandReqLineHandler,demandSearch,addDemand,editDemand,editSupply,demandSearchHandler,demandSearchVwBean,demandSearchVwHandler,demandBean,demandLBBean,inventoryItemNotesBean,notesBean,mfgSearchHandler,poSearchHandler,poDetail,soDetail,openPoOrdersHandler,hPoDetail,poHistoryBean,poHistoryHandler,poHistorySngHandler,poHistoryAcctMateHandler,searchPOHistory,poHItemHistoryHandler,poReceiptsHandler,itemHistoryVwBean,poNonStockPoolHandler,recievedOrdersHandler,nonStockSearchHandler,openSoOrdersHandler,shippedOrdersHandler,receivedPoOrdersHandler,soHistoryDetail,salesOrderInvoicesHandler,soHistoryHandler,stockItemsDetailBean,stockItemsVwBean,stockItemQuantitiesVwBean,stockLocationList,addSupply,supplyBean,supplyLBBean,supplyHistVwBean,supplyHistVwHandler,supplyHistoryDetail,supplyNotesHandler,supplyNotesBean,supplySearch,supplySearchHandler,vendorSearchHandler,vendorAddressesVwBean,supplySearchVwBean,supplySearchVwHandler,tradeUserBean,soSearchHandler,NextPhase,Trade,ERP,datawarehouse,sqlMapClient,jdbcUtil,jdbcSignatureDAO,pilotUsersVwDAO,soLinesAllDAO,securityRoleDAO,userLoginDAO,userLoginSignaturesDAO,profileLookupValuesDAO,userProfilesDAO,profilesDAO,userRolesDAO,userRolesVwDAO,userTradeGroupsDAO,partVwDAO,mfrDemandSummaryVwDAO,mfrSupplySummaryVwDAO,dwhAccountNotesVwDAO,userLoginTarget,mailService,version,mailSender,email,userLoginService,securityRoleService,acegiFilterChainProxy,httpSessionContextIntegrationFilter,log4jMDCUserFilter,securityRequestFilter,exceptionTranslationFilter,authenticationManager,daoAuthenticationProvider,rememberMeAuthenticationProvider,formAuthenticationProcessingFilter,jdbcLogError,accountAgentDAO,accountDAO,accountsVwDAO,addressDAO,addressTypeDAO,applicationsDAO,businessTypeDAO,businessTypeVwDAO,buyerQuotesDAO,buyerWorkgroupsVwDAO,buyersVwDAO,buyerQuotesVwDAO,commodityTypesVwDAO,commodityManagersVwDAO,contactDAO,contactAddressDAO,contactDetailsVwDAO,contactSearchVwDAO,countriesVwDAO,customerBuyerRequirementsVwDAO,customerRequirementsDAO,customerRequirementLinesDAO,customersVwDAO,customerAddressesVwDAO,erpCustomerContactsVwDAO,requirementLineAvlPartsDAO,customerReqLinesHistVwDAO,customerRequirementsVwDAO,demandVDAO,dateCodesVwDAO,demandHistVwDAO,demandStatusHistDAO,demandBuyersDAO,demandTypesVwDAO,demandNotesDAO,demandSearchVwDAO,erpProcedureDAO,erpPoHeaderDAO,erpPoLinesDAO,salesTermsVwDAO,shipMethodsVwDAO,itemHistoryVwDAO,inventoryItemNotesDAO,jdbcTradeSequenceDAO,jdbcTradeUtilDAO,jdbcControlNoDAO,locationsDAO,lightBoardDAO,manufacturersVwDAO,necxadmCacheObjDAO,xtradeCacheObjDAO,openSoLinesVwDAO,openPoLinesVwDAO,partClassVwDAO,packagingVwDAO,poLineSearchVwDAO,poHeaderDAO,poLineDAO,poSpecialInstructionsVwDAO,specialInstructionsVwDAO,poLineReceiptsVwDAO,phoneDAO,phoneTypeDAO,procedureDAO,productConditionsVwDAO,poHeaderVwDAO,purchaseOrdersAcctmateVwDAO,purchaseOrdersErpVwDAO,purchaseOrdersSngerpVwDAO,purchaseOrderReceiptsVwDAO,quoteStatusesDAO,quoteStatusHistDAO,reqBuyerStatusHistVwDAO,requirementBuyerStatusesDAO,requirementBuyersDAO,requirementStatusesDAO,requirementStatusHistDAO,rohsTypesVwDAO,salespersonsVwDAO,salesOrdersVwDAO,salesOrderInvoicesVwDAO,salesOrderShipmentsVwDAO,erpSoHeadersVwDAO,soHeaderDAO,erpSoLinesVwDAO,shippingLocationsVwDAO,soLineShipmentsVwDAO,stockItemQuantitiesVwDAO,stockItemsVwDAO,supplyVDAO,supplyHistVwDAO,supplyNotesDAO,supplySearchVwDAO,tradeOrganizationsMvDAO,userAccountsDAO,userApprovalLocationDAO,userApprovalLocationVwDAO,userAccountsVwDAO,vendorsVwDAO,vendorAddressesVwDAO,userSearchVwDAO,workGroupUsersVwDAO,workGroupsDAO,workGroupUsersDAO,soHeaderVwDAO,accountService,businessTypeTarget,buyersTarget,buyerQuotesTarget,cacheObjectTarget,contactTarget,commodityManagerTarget,commonTarget,customerService,customerAddressesService,partVwTarget,customerRequirementsTarget,demandTarget,lightBoardTarget,manufacturerTarget,poHistoryService,poService,soService,siService,purchasingTarget,stockItemTarget,userTarget,userAdminTarget,userAccountsServiceTarget,userApprovalLocationsTarget,userRolesTarget,userTradeGroupsTarget,vendorsServiceTarget,dbAdminTarget,salesTarget,arsSupplyDemandTarget,supplyTarget,soLinesAllTarget,validationServiceTarget,workGroupTarget,businessTypeService,buyersService,cacheObjectService,commodityService,contactService,commonService,buyerQuotesService,customerRequirementsService,arsSupplyDemandService,dbAdminService,demandService,lightBoardService,manufacturerService,salesService,purchasingService,supplyService,stockItemsService,userAccountsService,userAdminService,userApprovalLocationsService,userService,userRolesService,userTradeGroupsService,validationService,vendorsService,workGroupService,partVwService,soLinesAllService]; root of factory hierarchy
    2009-08-06 16:31:48,483 [,] INFO [org.springframework.transaction.jta.JtaTransactionManager] Using JTA UserTransaction: org.jboss.tm.usertx.client.ServerVMClientUserTransaction@6a21b2
    2009-08-06 16:31:48,483 [,] INFO [org.springframework.transaction.jta.JtaTransactionManager] Using JTA TransactionManager: com.arjuna.ats.jbossatx.jta.TransactionManagerDelegate@f3e54b

    [/code]

    Why is that?

  19. ankiton 11 Aug 2009 at 10:58 pm

    What will happen once when this static context doesn’t created initially and remains null.
    Next time, it will not created and beans will not be loaded again…

    I think it might create big problem………

  20. Pratap Shindeon 25 Aug 2009 at 5:49 pm

    Hello,

    This works great.
    Thanks for the solution.

  21. Guambinoon 27 Aug 2009 at 2:11 pm

    Hi, how I do get WebApplicationContext, cause the scopes such as session available?

    thankx

  22. Groovy, JMX and MBeans « Ice09on 31 Aug 2009 at 11:15 pm

    [...] access the bean with Groovy. Here’s how (it’s more or less a wrapper or extension of this post. The main trick is to implement ApplicationContextAware, which let Spring call the [...]

  23. Danon 18 Sep 2009 at 5:19 pm

    Was having trouble accessing spring beans from a web filter - had a method that worked fine in WebWork (Using DelegatingFilterProxy), but same model did not seem to be working with Struts2. This method worked fine for accessing spring beans from a filter in struts2.

  24. Beyon 29 Sep 2009 at 2:22 pm

    Hi Siegfried Bolz,

    thinks for this solution

    I was lost a lot of time to found this solution

  25. Sonalion 16 Oct 2009 at 12:15 pm

    Please make sure that the lazy-initialization in the contextApplicationContextProvider bean is set to false.

  26. Nikoon 09 Nov 2009 at 12:11 pm

    Thanks - you made my day!!! :-)

  27. sten17on 16 Nov 2009 at 2:30 pm

    Thank you very much.

  28. Bhushanon 18 Nov 2009 at 8:37 am

    nice thorough explanation, thanks

  29. Reneon 27 Nov 2009 at 2:27 pm

    Thanks for that, Sigi - YMMD!

    I was really lost getting out the spring application context. That helped me out.

    See you,
    Rene

  30. Anh Haon 03 Dec 2009 at 7:28 pm

    You can use the WebApplicationContextUtils to get the loaded Spring context in every where you want in the ServletContext, follow this example:

    ServletContext servletContext =this.getServletContext();

    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);

    User user = (User)wac.getBean(”user”);

  31. Ericon 15 Dec 2009 at 2:26 am

    One of the great helpful tips! Clean, concise, and complete. Thank you.

  32. [...] http://blog.jdevelop.eu/2008/07/06/access-the-spring-applicationcontext-from-everywhere-in-your-appl... [...]

  33. acaciobernardoon 09 Feb 2010 at 2:33 pm

    I used this in the validate method in my DTO bean associated with the form.
    Unfortunely I coud not understand the standard way of getting the context:

    ServletContext servletContext =this.getServletContext();
    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    The problem is thar I can’t get the this.getServletContext(); to compile…

    In my method all I have is a ValidationContext:
    public void validateEdicao(ValidationContext context).

    So, using the solution posted in this article did work. Thank you.

  34. Tor Arne Kvaløyon 03 Mar 2010 at 10:25 am

    Hey guys,

    I much easier way to get the spring application context from anywhere is to just have it autoinjected like this:

    @Autowired
    private ApplicationContext applicationContext;

    Tor :)

  35. nicknishon 09 Mar 2010 at 7:40 pm

    In the code when I do
    ApplicationContext ctx = AppContext.getApplicationContext();
    ctx is null,

    I have set lazy-init=false in applicationContext.xml

  36. nicknishon 09 Mar 2010 at 8:14 pm

    I think I figured it out, I hadn’t added

    contextConfigLocation
    /WEB-INF/applicationContext.xml

    to my web.xml

  37. Eric Mon 09 Mar 2010 at 11:13 pm

    Tor,

    Your solution doesn’t apply in this situation. The whole point is to be able to access the application context from a class that isn’t managed by Spring. You can’t ask Spring to inject dependencies into objects it doesn’t know anything about. ;)

    Eric M.

  38. Miguelon 14 Apr 2010 at 9:24 am

    Thank you. Simple and elegant solution.

  39. Rodrigoon 24 Apr 2010 at 8:49 pm

    It is working , thanks a lot!!

  40. Sheylaon 14 May 2010 at 5:30 pm

    Hello,

    I have a problem, ctx is null. Why. I think that spring file is incomplete. Can someone help me.

    Thanks.

    Sheyla

  41. SSon 01 Jun 2010 at 6:27 pm

    You are the best. It works Gr8!! Perfecto :-)

  42. Janeon 02 Jun 2010 at 10:56 am

    ctx is null. Bolz, can u pls help me out.

  43. Pabloon 15 Jun 2010 at 4:11 pm

    Thanks!!!!!! Very useful and elegant

  44. Mei Linon 16 Jul 2010 at 7:38 am

    I have a question. I have this dataSource on my applicationContext.xml.

    < bean id=”dataSourceArchive” class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”>
    <property name=”driverClassName” value=”oracle.jdbc.OracleDriver”/>
    <property name=”url” value=”jdbc:oracle:thin:@EMDSSERVER2:1521:EMDS2″/>
    <property name=”username” value=”dbo”/>
    <property name=”password” value=”dbo”/>
    </bean >

    What I wanna do is to set the “url” property of that “dataSourceArchive” and have it point to another database (EMDSQA instead of EMDS2).

    Thanks,

    Mei Lin

  45. Amadoon 16 Jul 2010 at 9:19 am

    hello, I hv a problem when calling :
    Honeypotbean honey = (HoneyPotBean) ctx.getBean(”honey”);
    if the class honey.java have a constructor that takes arguments, and there is no empty constructor, i’m receiving an error that says :
    failed to load the bean.
    can i load a bean that the correspondant java class takes arguments?

  46. Markon 04 Aug 2010 at 5:50 pm

    The code could be simplified to:

    === AppContext.java ===
    package com.abc;
    import org.springframework.context.ApplicationContext;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContextAware;
    public class AppContext implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    /**
    * Loaded during Spring initialization.
    */
    @Override
    public void setApplicationContext(ApplicationContext ctx)
    throws BeansException {
    applicationContext = ctx;
    }

    /**
    * Get access to the Spring ApplicationContext from anywhere in application.
    * @return Spring ApplicationContext
    */
    public static ApplicationContext getApplicationContext() {
    return applicationContext;
    }
    }
    === applicationContext.xml ===
    <bean id=”contextApplicationContextProvider” class=”com.abc.AppContext” . . .

  47. Anamikaon 25 Aug 2010 at 1:08 am

    Thanks, Good one

  48. Techon 25 Aug 2010 at 10:53 pm

    Thanks a lot for the post, it helped greatly!!!!

Trackback URI | Comments RSS

Leave a Reply

*
To prove that you're not a bot, enter this code
Anti-Spam Image

Note: To submit your comment you have to preview it at first!