{"id":1601,"date":"2010-11-23T10:02:26","date_gmt":"2010-11-23T15:02:26","guid":{"rendered":"http:\/\/www.andygibson.net\/blog\/?p=1601"},"modified":"2010-11-23T10:48:58","modified_gmt":"2010-11-23T15:48:58","slug":"injecting-string-resource-services-with-cdi","status":"publish","type":"post","link":"http:\/\/www.andygibson.net\/blog\/article\/injecting-string-resource-services-with-cdi\/","title":{"rendered":"Injecting String Resource Services with CDI"},"content":{"rendered":"<p>In <a href=\"http:\/\/www.andygibson.net\/blog\/article\/resource-bundles-in-jsf-2-0-applications\/\">this post<\/a> we looked at adding String resource bundles to our JSF applications to move our string constants into external resources that we can define for different locales. Now I want to extend that example to show how you can expand on that by using injection to access those resources.<br \/>\n<!--more--><br \/>\nWe finished off with a <code>MessageProvider<\/code> class that was responsible for fetching the resource bundle and had methods for fetching values from that bundle. We created this class manually and accessed the string resources from it. The problem here is that we need to keep on recreating the provider in each piece of code that needs it.<\/p>\n<h1>Doing things the CDI way<\/h1>\n<p>You could construct an instance of the <code>MessageProvider<\/code> each time you need it, but instead, we should look at how we can change our existing code to make it more CDI like. We can make the method that fetches the bundle a producer method and then inject the resource bundle where needed. If we give it a long enough scope, we can re-use it in the same request. <\/p>\n<p>First we&#8217;ll write a new Qualifier for the bundle so we can uniquely identify this bundle in a type safe manner. We may want to produce and inject multiple resources that will all be of the same type (<code>ResourceBundle<\/code>) so using a qualifier is a probably a good idea.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Qualifier\r\n@Target({ TYPE, METHOD, PARAMETER, FIELD })\r\n@Retention(RUNTIME)\r\n@Documented\r\npublic @interface MessageBundle {\r\n\r\n}\r\n<\/pre>\n<p>We&#8217;ll add a <code>@Produces<\/code> annotation to the <code>getBundle()<\/code> method.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\npublic class MessageProvider {\r\n\r\n     @Produces @MessageBundle \r\n     public ResourceBundle getBundle() {\r\n\t\tif (bundle == null) {\r\n\t\t\tFacesContext context = FacesContext.getCurrentInstance();\r\n\t\t\tbundle = context.getApplication().getResourceBundle(context, &quot;msgs&quot;);\r\n\t\t}\r\n\t\treturn bundle;\r\n\t}\r\n\t...\r\n        ...\r\n        ...\r\n}\r\n<\/pre>\n<p>Now we just need to inject this into our bean and use the injected bundle instead of constructing our own instance of the <code>MessageProvider<\/code> class.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Named\r\n@RequestScoped\r\npublic class SomeBean {\r\n\r\n\t@Inject @MessageBundle\r\n\tprivate ResourceBundle bundle;\r\n\t\t\t\r\n\tpublic String getMessage() {\r\n\t\tString msg = null;\r\n\t\tString key = &quot;someMessage&quot;;\r\n\t\ttry {\r\n\t\t\tmsg = bundle.getString(key);\r\n\t\t} catch (MissingResourceException e) {\r\n\t\t\tmsg = &quot;??&quot;+key+&quot;?? is missing!&quot;;\r\n\t\t}\r\n\t\treturn MessageFormat.format(msg, &quot;SomeValue&quot;);\t\t\t\t\r\n\t}\r\n}\r\n<\/pre>\n<p>While this is more CDI-ish, it does have the problem that it consists of more code since we re-produce the exception handling code each time. So we probably need to use something that consists of more than just the bundle, say maybe the whole <code>MessageProvider<\/code> class with the methods to fetch key values. The beauty here is that we we don&#8217;t need to do anything to achieve this except give the <code>MessageProvider<\/code> class a scope : <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@RequestScoped\r\npublic class MessageProvider {\r\n    ....\r\n    ....\r\n}\r\n<\/pre>\n<p>No we just add an injection point for the <code>MessageProvider<\/code> class in our bean. We&#8217;ll create a new bean for this called <code>AnotherBean<\/code> :<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\n@Named\r\n@RequestScoped\r\npublic class AnotherBean {\r\n\r\n\t@Inject\r\n\tprivate MessageProvider provider;\r\n\t\r\n\tpublic String getFirstNameCaption() {\r\n\t\treturn provider.getValue(&quot;firstName&quot;);\r\n\t}\r\n}\r\n<\/pre>\n<p>In our JSF page we add a reference to the property to display the value :<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nFirst Name Caption = #{anotherBean.firstNameCaption}\r\n<\/pre>\n<p>This results in the following text being displayed :<\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\nFirst Name Caption = First Name\r\n<\/pre>\n<p>You might notice that our old bean is still using the resource bundle from the producer method, and everything is still working. This is because beans can be injectable and still contain producer methods. You will also find that across the request, the injected instance of the bundle is always the same as the one in <code>provider.getBundle()<\/code>. This is because every time the bundle is produced, the <code>MessageProvider<\/code> is constructed and put into request scope and the bundle value is returned. This bundle value is retained in the <code>MessageProvider<\/code> instance. No matter how many times we inject the bundle, the same one is used, even though we didn&#8217;t give it a request scope. This is actually a useful thing because the resource bundle cannot be proxied by CDI so it cannot be put into request scope itself, but it can be put into request scope if it is contained in another bean (in this case, the <code>MessageProvider<\/code>).<\/p>\n<p>This shows not only how flexible CDI is in making objects available to your applications, but how easy it is to tweak how those objects are made available, all without changing the underlying code.<\/p>\n<p>Next time we&#8217;ll look at using event handling to notify us of missing resources.<\/p>\n<p>You can <a href='http:\/\/www.andygibson.net\/blog\/wp-content\/uploads\/2010\/10\/resourceInjectionDemo.zip'>download the Maven source code<\/a> for this project and run it locally by unzipping it and running <code>mvn clean jetty:run<\/code> in the command line and going to <a href=\"http:\/\/localhost:8080\/resourcedemo\/\">http:\/\/localhost:8080\/resourcedemo\/<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this post we looked at adding String resource bundles to our JSF applications to move our string constants into external resources that we can define for different locales. Now I want to extend that example to show how you can expand on that by using injection to access those resources.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[63],"tags":[49,6,72,50,67,32],"_links":{"self":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1601"}],"collection":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/comments?post=1601"}],"version-history":[{"count":9,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1601\/revisions"}],"predecessor-version":[{"id":1666,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/posts\/1601\/revisions\/1666"}],"wp:attachment":[{"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/media?parent=1601"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/categories?post=1601"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.andygibson.net\/blog\/wp-json\/wp\/v2\/tags?post=1601"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}