Simpler JPA with Spring Data-JPA

How to configure your Spring application with Simple CRUD configuration with Spring Data-JPA.



1. Add Spring Data-JPA to project configuration. In your Maven pom.xml file

<dependency>
   <groupId>org.springframework.data</groupId>
   <artifactId>spring-data-jpa</artifactId>
   <version>1.0.2.RELEASE</version>
</dependency>



2. Configure JPA Entity

...

@Entity
public class Product {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @Column(name = "id")
  private Long id;

  @NotNull
  @Column(unique = true)
  private String productId;

  @NotNull
  private Integer quantity;

  ...
}



3. Configure Typed Repository Interface

Spring Data JPA will create the beans for us.

package com.gordondickens.myapp.repository;

import org.springframework.data.repository.CrudRepository;
import com.gordondickens.myapp.entity.Product;

public interface ProductRepository
   extends CrudRepository<Product, Long> {}



4. Configure the application context

Note: this example uses Hibernate and HSQL

<!-- Directory to scan for repository classes -->
<jpa:repositories
   base-package="com.gordondickens.myapp.repository" />

<bean class="org.springframework.orm.jpa.JpaTransactionManager"
  id="transactionManager">
  <property name="entityManagerFactory"
      ref="entityManagerFactory" />
  <property name="jpaDialect">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
  </property>
</bean>

<bean id="entityManagerFactory"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="jpaVendorAdapter">
    <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
      <property name="generateDdl" value="true" />
      <property name="database" value="HSQL" />
    </bean>
  </property>
</bean>



5. Inject the Repository

In our service class & tests we use the repository to execute our crud methods. Repository Methods: count(), exists(), delete(), deleteAll(), findOne(), findAll(), save().

public class ProductServiceImpl extends ProductService {

   @Autowired
   ProductRepository productRepository;

  ...
}

See Part 2 – Adding Queries to Spring Data-JPA



Summary

The Spring Data project abstracts away basic data management concepts. In addition to support for traditional relational methodologies, Spring Data provides support for NoSQL Graph, Key-Value and Map-Reduce types. As we saw in the above example configuring CRUD style applications is fairly trivial and Spring provides a convenient configuration for the typical cookie cutter code.

Click here to see my other blog which lists the annotations in “Spring Data-Commons” and “Spring Data-JPA”.




Want to Learn More?

Learn more about Spring by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Hibernate, JPA, Spring, Spring Data, Spring Framework | Tagged , , , , , , | 6 Comments

Quick Install for tcServer 2.5 with Spring Insight in STS

Installation & Config

  1. Download tcServer Developer’s Edition – current version is 2.5.1 (free registration required)
  2. Make a directory for tcServer (such as /opt/tcserver or c:\tcserver)
  3. Unzip the downloaded file into that directory
  4. Type at command line in your tcServer directory (.sh for unix/mac, .bat for Windows): tcruntime-instance.sh create myInsight -t insight
  5. Start STS (I am using 2.7.1)
  6. From menu: File > New > Other… > Server > Server
  7. Scroll to VMware, choose VMware vFabric tcServer 2.5
  8. Click Configure Runtime Environments link
  9. Add new tcServer, setting the location to your tcServer directory, press OK
  10. Choose the newly configured Server Runtime Environment from the drop down
  11. Press Next
  12. Choose Existing Instance radio button
  13. Choose myInsight from the dropdown



Configuring for Tomcat 6

By default, the tcruntime-instance script configures Tomcat 7.

To use Tomcat 6 instead:
Determine the version of Tomcat 6 that is available with tcServer – the version is in the directory name. For tcServer 2.5.1, the directory is <tcServer Dir>/tomcat-6.0.32.C.RELEASE, so we know that our version is “6.0.32.C.RELEASE“.
Now execute the command: tcruntime-instance.sh create myInsight -t insight --version 6.0.32.C.RELEASE



Deploying & Running with Insight

  1. R-click on a web app, Run on Server (or drag and drop to tcServer in Server view)
  2. If server not running press the Green play arrow in the Server view toolbar
  3. Popup: Spring Insight is Available… enable gathering of metrics? – Click YES
  4. Connect to your app – e.g. http://localhost:8080/myapp
  5. Connect to Insight – http://localhost:8080/insight




Want to Learn More?

Learn more about developing Spring Apps by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in Eclipse, Installation, Spring, Spring Insight, STS, tcServer, Tomcat | Tagged , , , , , , | 2 Comments

RESTful MVC Features in Spring 3.0 and 3.1

Below is a feature summary you must know to use Spring’s MVC RESTful Web Services. This article will show the features available, but not discuss pros & cons, use-cases or sell you on the benefits of REST.



PUT & POST in Browser Based Clients

Browsers do not allow PUT & DELETE – In web.xml configure HiddenHttpMethodFilter & on the page add the following inside your form <input type="hidden" name="_method" value="PUT"/>, with form submit set to POST. If using the Spring <form:form> tag, the hidden field is created for you, use any of the standard 7 HTTP verbs as desired.



Receiving Values in the URL Path, the RESTful Way

@PathVariable in Controller methods to extract values from the path.



You Rarely Need to Write Custom Parsers

<mvc:annotation-driven/> – automatically registers several marshallers simply with presence of corresponding jar in classpath

Type group:artifact:current-version
JAXB2 com.sun.xml.bind:jaxb-impl:2.2.4
JAXP javax.xml:jaxp-api:1.4.2
Atom/RSS rome:rome:1.0
JSON org.codehaus.jackson:jackson-mapper-asl:1.8.3



Configure – Don’t Code

Automatic Marshalling & Unmarshalling of XML, JSON, ATOM/RSS data
Controller annotations: @RequestBody & @ResponseBody
Example of JAXB2 Configuration in my OXM blog post named http://gordondickens.com/wordpress/2011/02/07/sending-beans-as-xml-with-jmstemplate/



Sending HTTP Response Codes to Clients

Success response status with @ResponseStatus controller method annotation.
Exception handling with @ExceptionHandler annotation on controller methods OR custom classes, also with annotated @ResponseStatus.
Note: @ResponseStatus disables the default behavior of void controller methods automatically returning the view.



Content Negotiation

Accept Header in Browser Based Clients

The HTML Accept header is not a reliable option for browser based clients to request content type. See Content Negotiation below.

Managing Client Content Type Requests

The HTTP Accept header is the typical REST vehicle for receiving the client’s requested MIME content type (application/JSON, application/XML, etc.)

Content Negotiation – Flexible Config Options

Spring’s ContentNegotiatingViewResolver for configuring client request data format. Several methods beyond the standard “Accept” header which will not work if you have browser based clients (Accept header, url extension, parameter, Java Activation Framework). URL extension (referred to as file extension) allows a URL to be appended with a string which can be mapped to a MIME type.

<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
  <property name="mediaTypes">
    <map>
      <entry key="json" value="application/json" />
      <entry key="xml" value="application/xml" />
      <entry key="htm" value="text/html" />
    </map>
  </property>
  <property name="defaultContentType" value="text/html" />
</bean>

The same shortcut keys can be used in a parameter where URL can have “?format=json”. For JAF, the jar contains a /lib/mime.types file with mapped types already defined.

Type group:artifact:current-version
Java Activation javax.activation:activation:1.1.1
Java Mail javax.mail:mail:1.4.1



Client Side with RestTemplate

Spring’s RestTemplate is for client side development. In the Spring Template style, simply, set the URL, invoke the method & process the results. The main extension points in Spring Templates are done through Callbacks.

HTTP Method RestTemplate Method
DELETE delete(java.lang.String, java.lang.Object...)
GET getForObject(java.lang.String, java.lang.Class, java.lang.Object...), getForEntity(java.lang.String, java.lang.Class, java.lang.Object...)
HEAD headForHeaders(String url, String... urlVariables)
OPTIONS optionsForAllow(String url, String... urlVariables)
POST postForLocation(String url, Object request, String... urlVariables)

RestTemplate Callbacks

Callback Description Interface
RequestCallback Called when execute method is invoked public interface RequestCallback { void doWithRequest(ClientHttpRequest request) throws IOException;
}
AcceptHeaderRequestCallback Processing the Accept headers public void doWithRequest(ClientHttpRequest request)
HttpEntityRequestCallback Writes provided object to output stream public void doWithRequest(ClientHttpRequest httpRequest)



REST Improvements in Spring 3.1

Customizable @MVC

  • Custom @ExceptionHandler support for @Controller methods
  • Custom @ExceptionHandler support for @RequestBody & @ResponseBody
  • You can write a BeanPostProcessor to change AnnotationMethodHandlerAdapter after construction
  • Auto-detection of custom HttpMessageConverters – for example custom MyMappingJacksonHttpMessageConverter
  • Support for custom message codes resolver with <mvc:annotation-driven/>
<mvc:annotation-driven>
    <mvc:custom-web-argument-resolvers>
        <bean class="org.example.MyWebArgumentResolver"/>
    </mvc:custom-web-argument-resolvers>
</mvc:annotation-driven>
<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>
<mvc:annotation-driven message-codes-resolver="org.example.MyMessageCodesResolver"/>

REST Enhancements

  • Interceptors for RestTemplate
  • ClientHttpRequestInterceptor – ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
  • bufferRequestBody property to the SimpleClientHttpRequestFactory to handle large payloads with RestTemplate
  • New WebRequest.checkNotModified(String) // only had long support previously
  • New @ResponseEntity
  • To support OAuth with ClientHttpRequestInterceptors



Other REST Concepts



HATEOAS

Hypermedia as the Engine of Application State

WADL

Web Application Description Language



Summary

Spring MVC REST helps us with:

  • The power of <mvc:annotation-driven/> provides us the automatic marshalling/unmarshalling of content in REST
  • The configuration flexibility of ContentNegotiatingViewResolver for our browser based clients




Want to Learn More?

Learn more about Spring REST by attending a Spring Training class at Chariot, or contact us for onsite training.



Follow Chariot Education on Twitter

for Special Training offers

Posted in REST, Spring, Spring MVC, Web Services | Tagged , , , | 1 Comment

SpringSource Tool Suite – Eclipse for Spring Developers

Spring developers using Eclipse should take a close look at SpringSource Tool Suite (STS). STS is a FREE IDE, based on Eclipse with many of the essential tool to assist Spring developers. http://www.springsource.com/developer/sts. The major plugin to Eclipse is Spring IDE.

I recently authored the DZone RefCard – Eclipse Tools for Spring: The SpringSource Tool Suite. At Chariot Solutions, I teach the official Spring Courses. All the course material installs with STS and the student’s labs/solutions are configured within STS. With some of the more inquisitive students where I would be faced with questions about STS features that I did not truly understand. Like many developers, I don’t read manuals until I have to. What I discovered is that Eclipse plugin developers do not create full documentation, they write “New and Noteworthy” documents that address new features and product improvements. So, to get an understanding of what features are available and how they work, one has to read all of these documents to get an idea of the features available. There is not any comprehensive documentation available.

I am a huge fan of the DZone RefCardz. In six pages you get a nice quick start on a technology. Since I love to learn and share, this seemed like a great opportunity to focus on the core Spring features in STS.

My first attempt was to go through the menus and find the Spring specific features. This was helpful, but left many questions unanswered.


First Places to Look

  • Right Click on a Project > Spring Tools
  • Preferences > Spring

After a good chunk of time, I realized that this would be far more than 6 pages of material, so I narrowed the RefCard down to simply core Spring features.


Feature Categories

  • Core Spring
  • Spring & OSGi (formerly Spring Dynamic Modules & Spring dm Server)
  • Spring Dashboard
  • Groovy
  • Grails
  • Spring Roo
  • Spring Batch
  • Spring Integration
  • Spring Web Flow
  • tc Server
  • CloudFoundry

Obviously, the essential items for core Spring are covered in the RefCard (space permitting).


Cool Stuff

  • Visualizers
  • Validation
  • Spring Configuration, XML Content Assist
  • Spring Focussed, Java Content Assist
  • Spring AOP

I am planning on a series of ScreenCasts focussing on specific features of STS. In the meantime, if you have any questions, feel free to contact me mailto:gdickens@chariotsolutions.com



Want to Learn More?

Learn more about what goes on Spring Context by attending a Core Spring Training class at Chariot.



Follow Chariot Education on Twitter

for Special Training offers

Posted in AOP, AspectJ, Eclipse, Grails, Groovy, Java, Roo, Spring, Spring AOP, Spring Batch, Spring Framework, Spring Integration, Spring MVC, Spring Roo, Web Flow | Tagged , , , , , , , , | 3 Comments

How to Configure Spring MVC in a Web Server

Below is a Pencast describing how to configure a web server for web page traffic and SOAP web service traffic.


If you do not see the Flash player below, click on the following link to listen & view the Pencast.
Spring 3 MVC Configuration



Want to Learn More?

Learn more about what goes on Spring Context by attending a Core Spring Training class at Chariot.



Follow Chariot Education on Twitter

for Special Training offers



Posted in Spring | Tagged , , , , , , | Leave a comment

Annotation Reference for Spring Projects

Annotations are available for Spring and Java projects. I was unsuccessful in finding a single consolidated set of the annotations. So, I thought “What a great gap to fill.” However, what I thought would be a fairly simple endeavor, turned out to be a rabbit hole of research.

Below I have aggregated Spring (up to 3.1) and Java Annotations (over 500 annotations), most of which are used by Spring. JSR-168, JSR-220, JSR-222, JSR-224, JSR-250, JSR-299, JSR-303, JSR-314, JSR-315, JSR-317, JSR-318, JSR-330 & Hibernate 3.x.


Spring & Javax Annotations

Note: There are multiple tabs, see links at bottom of table.



Click here for Full Page Version


download sheetDownload Sheets – updated 19-Sep-2011


DISCLAIMER:

The content is not guaranteed to be 100% accurate. Please comment on any issues or email gordon@gordondickens.com



Want to Learn More?

Learn more about what goes on Spring Context by attending a Core Spring Training class at Chariot.



Follow Chariot Education on Twitter

for Special Training offers



Posted in Annotations, AOP, Hibernate, Java, JMX, JPA, JUnit, REST, SOAP, Spring, Spring AOP, Spring Batch, Spring Framework, Spring Integration, Spring MVC, Spring Roo, Spring Security, Web Flow, Web Services | Tagged , , , , , , , , , , , , , , | 7 Comments

Spring Expression Language (SpEL) Predefined Variables

Spring 3.0 introduced Spring Expression Language (SpEL). There are two variables that you have available “systemProperties” and “systemEnvironment“. SpEL allows us to access information from our beans and system beans information at runtime (late binding).

These can be applied to bean fields as defaults using the JSR-303 @Value annotation on a field or in XML with the <bean ... value="" /> options.

  • systemProperties – a java.util.Properties object retrieving properties from the runtime environment
  • systemEnvironment – a java.util.Properties object retrieving environment specific properties from the runtime environment

We can access specific elements from the Properties object with the syntax:

  • systemProperties['property.name']
  • systemEnvironment['property.name']



Define a bean:

public class MyEnvironment {

  @Value("#{ systemProperties['user.language'] }")
  private String varOne;

  @Value("#{ systemProperties }")
  private java.util.Properties systemProperties;

  @Value("#{ systemEnvironment }")
  private java.util.Properties systemEnvironment;

  @Override
  public String toString() {
    return "\n\n********************** MyEnvironment: [\n\tvarOne="
      + varOne + ", \n\tsystemProperties=" + systemProperties
      + ", \n\tsystemEnvironment=" + systemEnvironment + "]";
  }
}

Register the “MyEnvironment” bean in your Spring context and create a JUnit test to display the variables.

To populate a variable from one of your properties from a properties file use: @Value("${some.property.of.mine}")

Posted in SpEL, Spring, Spring Framework | Tagged , , , , , , , | Leave a comment

Eclipse Indigo Bogdown

I am experimenting with Eclipse Indigo 3.7.m6a with the nightly builds of SpringSource Tool Suite (a.k.a. Spring IDE, STS).

I have a Project with many small projects and it sometimes takes quite a long time to start, bordering on my patience level, which has been winning and I have been “Force Quit”ting the application.

1. From the command line using Maven, clean the project, rebuild and generate the Eclipse project files.

mvn clean install eclipse:clean eclipse:eclipse

2. Start Eclipse from the command prompt:

eclipse -clean -consolelog -data /mycode/myworkspace/

In my latest attempt, the console shows all the projects built, however, the status bar displays “Web (2.2-2.4) Validator” which has been going and going and going… impatience Wins! -FQ

When all else fails, create a new workspace directory and reimport your projects. This stinks because you have to re-configure your Preferences again, but it’s easier than fighting with it.

Remember it is still pre-production release, expect Windows like behavior. Wait for it to start, be gentle, do NOT click on anything before it sits quietly or it will lock up.


Solution Update – 07-May-11

I reinstalled Eclipse Indigo JEE version with the following Plugins…

  1. M2Eclipse – http://m2eclipse.sonatype.org/sites/m2e
  2. AJDT – http://download.eclipse.org/tools/ajdt/37/dev/update
  3. eGit (part of Eclipse package) – http://download.eclipse.org/releases/indigo (see note below)
  4. Groovy Eclipse – http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.7/
  5. STS (Need Groovy Eclipse first) – http://dist.springsource.com/snapshot/TOOLS/nightly/e3.7
  6. Gradle – http://dist.springsource.com/milestone/TOOLS/gradle

NOTE: STS & Groovy should be installed last. They have several dependencies such as M2Eclipse and AJDT so they must be installed first. Also, unless you are using the JIRA plugin (I think you must purchase it, you will have to deselect it and do not check the last option which is either “other or optional”. These are STS-Package Feature Group & STS-Runtime Feature Group.

NOTE: I was only able to get eGit to install from: http://download.eclipse.org/egit/updates-nightly

Posted in Eclipse, Spring | Tagged , , , , , , , , , , | 2 Comments

Don’t Use JmsTemplate in Spring!

Stop Using JmsTemplate!

JmsTemplate is easy for simple message sending. What if we want to add headers, intercept or transform the message? Then we have to write more code. So, how do we solve this common task with more configurability in lieu of more code? First, lets review JMS in Spring.




Spring JMS Options

  1. JmsTemplate – either to send and receive messages inline
    1. Use send()/convertAndSend() methods to send messages
    2. Use receive()/receiveAndConvert() methods to receive messages. BEWARE: these are blocking methods! If there is no message on the Destination, it will wait until a message is received or times out.
  2. MessageListenerContainer – Async JMS message receipt by polling JMS Destinations and directing messages to service methods or MDBs

Both JmsTemplate and MessageListenerContainer have been successfully implemented in Spring applications, if we have to do something a little different, we introduce new code. What could possibly go wrong?


Future Extensibility?

On many projects new use-cases arise, such as:

  • Route messages to different destinations, based on header values or contents?
  • Log the message contents?
  • Add header values?
  • Buffer the messages?
  • Improved response and error handling?
  • Make configuration changes without having to recompile?
  • and more…

Now we have to refactor code and introduce new code and test cases, run it through QA, etc. etc.




A More Configurable Solution!

It is time to graduate Spring JmsTemplate and play with the big kids. We can easily do this with a Spring Integration flow.


How it is done with Spring Integration

Here we have a diagram illustrating the 3 simple components to Spring Integration replacing the JmsTemplate send.

  1. Create a Gateway interface – an interface defining method(s) that accept the type of data you wish to send and any optional header values.
  2. Define a Channel – the pipe connecting our endpoints
  3. Define an Outbound JMS Adapter – sends the message to your JMS provider (ActiveMQ, RabbitMQ, etc.)

Simply inject this into our service classes and invoke the methods.



Immediate Gains

  • Add header & header values via the methods defined in the interface
  • Simple invokation of Gateway methods from our service classes
  • Multiple Gateway methods
  • Configure method level or class level destinations



Future Gains

  • Change the JMS Adapter (one-way) to a JMS Gateway (two-way) to processes responses from JMS
  • We can change the channel to a queue (buffered) channel
  • We can wire in a transformer for message transformation
  • We can wire in additional destinations, and wire in a “header (key), header value, or content based” router and add another adapter
  • We can wire in other inbound adapters receiving data from another source, such as SMTP, FTP, File, etc.
  • Wiretap the channel to send a copy of the message elsewhere
  • Change the channel to a logging adapter channel which would provide us with logging of the messages coming through
  • Add the “message-history” option to our SI configuration to track the message along its route
  • and more…




Optimal JMS Send Solution



The Spring Integration Gateway Interface

Gateway provides a one or two way communication with Spring Integration. If the method returns void, it is inherently one-way.

The interface MyJmsGateway, has one Gateway method declared sendMyMessage(). When this method is invoked by your service class, the first argument will go into a message header field named “myHeaderKey”, the second argument goes into the payload.

package com.gordondickens.sijms;

import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.Header;

public interface MyJmsGateway {
    @Gateway
    public void sendMyMessage(@Header("myHeaderKey") String s, Object o);
}



Spring Integration Configuration

Because the interface is proxied at runtime, we need to configure in the Gateway via XML.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:jms="http://www.springframework.org/schema/integration/jms"
        xmlns:si="http://www.springframework.org/schema/integration"
        xsi:schemaLocation="http://www.springframework.org/schema/integration/jms

http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.0.xsd

http://www.springframework.org/schema/integration

http://www.springframework.org/schema/integration/spring-integration-2.0.xsd

http://www.springframework.org/schema/beans

          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <import resource="classpath:META-INF/spring/amq-context.xml"/>

    <!-- Pickup the @Gateway annotation -->
    <si:annotation-config/>

    <si:poller default="true">
      <si:interval-trigger interval="500"/>
    </si:poller>

    <!-- Define the channel (pipe) connecting the endpoints -->
    <si:channel id="myRequestChannel"/>

    <!-- Configure the Gateway to Send on the channel -->
    <si:gateway id="myJmsGateway"
        service-interface="com.gordondickens.sijms.MyJmsGateway"
        default-request-channel="myRequestChannel"/>

    <!-- Send message to JMS -->
    <jms:outbound-channel-adapter channel="myRequestChannel"
        connection-factory="connectionFactory"
        destination="my.inbound.queue"/>
</beans>



Sending the Message

package com.gordondickens.sijms;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration("classpath:/com/gordondickens/sijms/JmsSenderTests-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class JmsSenderTests {

    @Autowired
    MyJmsGateway myJmsGateway;

    @Test
    public void testJmsSend() {
        myJmsGateway.sendMyMessage("myHeaderValue", "MY PayLoad");
    }
}




Summary

  • Simple implementation
  • Invoke a method to send a message to JMS – Very SOA eh?
  • Flexible configuration
  • Reconfigure & restart WITHOUT recompiling – SWEET!




Followup

Chariot EducationI teach the official SpringSource “Enterprise Integration with Spring” course. See the upcoming schedule or contact us for custom, private or onsite training.


Spring Integration in ActionSpring Integration in Action

A hands-on guide to Spring-based messaging and integration. After addressing the core messaging patterns, such as those used in transformation and routing, the book turns to the adapters that enable integration with external systems.




Posted in ActiveMQ, JMS, Spring, Spring Framework, Spring Integration | Tagged , , , , , , , , | Leave a comment

What’s in my Spring Context?

When we are learning Spring, there are times we are not sure which beans are in the Spring context. Especially when we use convenient features of Spring 3 such as <context:annotation-driven/> or <context:component-scan/>. As developers, we want to inspect the classes that are automatically registered providing the opportunity to look at the source code and javadocs to see what each class does.


JUnit Tests get Application Context

Our JUnit tests have the ability to inject the Application Context. This is one of the many benefits of @RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(value = "/META-INF/spring/test-app-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class BeansInContextTest {

     @Autowired
     ApplicationContext applicationContext;

Simple Code

Let’s loop through all the beans that are defined or discovered with the following code.

@Before
public void setup() {
  logger.debug("********************");
  String[] beans = applicationContext.getBeanDefinitionNames();
  for (String o : beans) {
    logger.debug("________________________");
    logger.debug("BEAN = " + o);
    logger.debug("\tType = " + applicationContext.getType(o));
    String[] aliases = applicationContext.getAliases(o);
     if (aliases != null && aliases.length > 0) {
       for (String a : aliases) {
         logger.debug("\tAliased as: " + a);
       }
     }
  }

  logger.debug("********************");
  logger.debug("*** Number of Beans = {} ***",
    applicationContext.getBeanDefinitionCount());
  logger.debug("********************");
  }
}

What is the Alias?

We can define beans with “id” which by XML law requires it to be unique per file. This restricts us in the ability to use special symbols for the name should we want to. I recommend using “id” unless absolutely necessary. However, should we what to refer to the bean with multiple names or use special symbols, we can use the “name” attribute. By comma separating the tokens, we have the opportunity to refer to a bean with any of the tokens provided.

<bean name="mailServer/default, mailServer" class="..."/>

If no, “id” is provided, the first token becomes the primary and the subse quent tokens become aliases. Does this matter in the usage of the beans? No. But to find “all” the names of the beans, we would display the aliases in addition to the bean names.

The Full Test Code

package com.chariot.sample;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@ContextConfiguration(value = "/META-INF/spring/test-app-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class BeansInContextTest {
  private final Logger logger = LoggerFactory
    .getLogger(BeansInContextTest.class);

  @Autowired
  ApplicationContext applicationContext;

  @Before
  public void setup() {
    logger.debug("********************");
    String[] beans = applicationContext.getBeanDefinitionNames();
    for (String o : beans) {
      logger.debug("________________________");
      logger.debug("BEAN = " + o);
      logger.debug("\tType = " + applicationContext.getType(o));
      String[] aliases = applicationContext.getAliases(o);
      if (aliases != null && aliases.length > 0) {
        for (String a : aliases) {
          logger.debug("\tAliased as: " + a);
        }
      }
    }

    logger.debug("********************");
    logger.debug("*** Number of Beans = {} ***",
      applicationContext.getBeanDefinitionCount());
    logger.debug("********************");
  }
}

Sample Bean Context

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/context

      http://www.springframework.org/schema/context/spring-context-3.0.xsd">

  <context:annotation-config/>

  <bean id="myBean" class="MyCoolBean"/>

</beans>

Experiment and Have Fun

Add beans to the config file. Import other config files and see what happens.

Wanna Learn More?

Learn more about what goes on Spring Context by attending a Core Spring Training class at Chariot.



Follow Chariot Education on Twitter

for Special Training offers



Posted in Spring | Tagged | Leave a comment