Showing posts with label Spring. Show all posts
Showing posts with label Spring. Show all posts

Sunday, January 11, 2015

No separate schema definition for p-namespace and c-namespace.



  1. p-namesapce (Parameter namespace)
  2. c-namespace (Constructor namespace)

p-namesapce (Parameter namespace)

p-namespace simplifies the setter-based dependency injection code by enabling you to use the parameters to be injected as attributes of bean definition instead of the nested <property> elements.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 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.xsd">
    <bean id="addr1" class="com.ixi.samples.spring.cpns.Address">
        <property name="houseNo" value="2106"/>
        <property name="street" value="Newbury St"/>
        <property name="city" value="Boston"/>
        <property name="zipCode" value="02115-2703"/>
    </bean>
    <bean id="constArgAnotherBean" class="com.pfl.samples.spring.cpns.Person">
        <property name="firstName" value="Joe"/>
        <property name="lastName" value="John"/>
        <property name="age" value="35"/>
        <property name="address" ref="addr1"/>
    </bean>
</beans> 

with p-namespace, you can write this as:
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="addr1" class="com.ixi.samples.spring.cpns.Address" 
             p:houseNo="2106" 
             p:street="Newbury St" 
            p:city="Boston" 
            p:zipCode="02115-2703"/>
    <bean name="person1" class="com.ixi.samples.spring.cpns.Person" 
            p:firstName="Joe" 
            p:lastName="John" 
            p:age="35" 
           p:address-ref="addr1"/>     
</beans>  

It is simple! All you need to do is

  1. Add the p namespace URI (xmlns:p="http://www.springframework.org/schema/p") at the configuration xml with namespace prefix p. Please note that it is not mandatory that you should use the prefix p, you can use your own sweet namespace prefix :)
  2. For each nested property tag, add an attribute at the bean with name having a format of p:<property-name> and set attribute value to the value specified in the nested property element.
  3. If one of your property is expecting another bean, then you should suffix -ref to your property name while constructing the attribute name to use in bean definition. For eg, if you property name is address then you should use attribute name as address-ref

c-namespace (Constructor namespace)

c-namespace is similar to p-namespace but used with constructor-based dependency injection code. It simplifies the constructor-based injection code by enabling you to use the constructor arguments as attributes of bean definition rather than the nested <constructor-arg> elements.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 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.xsd">
 <bean id="addr1" class="com.pfl.samples.spring.cpns.Address">
  <constructor-arg name="houseNo" value="2106"/>
  <constructor-arg name="street" value="Newbury St"/>
  <constructor-arg name="city" value="Boston"/>
  <constructor-arg name="zipCode" value="02115-2703"/>
 </bean>
 <bean id="constArgAnotherBean" class="com.pfl.samples.spring.cpns.Person">
  <constructor-arg name="firstName" value="Joe"/>
  <constructor-arg name="lastName" value="John"/>
  <constructor-arg name="age" value="35"/>
  <constructor-arg name="address" ref="addr1"/>
 </bean>  
</beans> 

and with c-namespace, it can be written as
<?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:c="http://www.springframework.org/schema/c"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="addr1" class="com.pfl.samples.spring.cpns.Address"
        c:houseNo="2106" c:street="Newbury St"
        c:city="Boston" c:zipCode="02115-2703"/>
    <bean name="person1" class="com.pfl.samples.spring.cpns.Person"
        c:firstName="Joe" c:lastName="John"
        c:age="35" c:address-ref="addr1"/>
</beans>    

It is same as p-namespace. All you need to do is
Add the c namespace URI (xmlns:c="http://www.springframework.org/schema/c") at the configuration xml with namespace prefix c. The prefix is not mandatory like p-namespace
For each nested constructor-arg eleemnt, add the attribute with name c:<argument-name> to the bean definition and set the actual argument value as attribute value.
If one of your constructor argument is expecting another bean, then you should suffix -ref to your argument name while constructing the attribute name to use in bean definition (like p-namespace). For eg, if you argument name is address then you should use address-ref

Well, the above code has an issue though. It is using the constructor argument names and that will be available only if the code is compiled with debug enabled which may not be the case with production code. So, you will have to use the index rather than the argument names. With index, we can rewrite the above code as follows.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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.xsd">
    <bean id="addr1" class="com.pfl.samples.spring.cpns.Address">
        <constructor-arg index="0" value="2106"/>
        <constructor-arg index="1" value="Newbury St"/>
        <constructor-arg index="2" value="Boston"/>
        <constructor-arg index="3" value="02115-2703"/>
    </bean>
    <bean id="constArgAnotherBean" class="com.pfl.samples.spring.cpns.Person">
        <constructor-arg index="0" value="Joe"/>
        <constructor-arg index="1" value="John"/>
        <constructor-arg index="2" value="35"/>
        <constructor-arg index="3" ref="addr1"/>
    </bean>
</beans> 

With c-namespace:

<?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:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name="addr1" class="com.pfl.samples.spring.cpns.Address"
        c:_0="2106" c:_1="Newbury St"
        c:_2="Boston" c:_3="02115-2703"/>
    <bean name="person1" class="com.pfl.samples.spring.cpns.Person"
        c:_0="Joe" c:_1="John"
        c:_2="35" c:_3-ref="addr1"/>
</beans> 

You may notice that there is not much difference rather than using index in the place of argument name. Also, the index should be prefixed by _(underscore) to make it as a valid xml attribute name.

You can use both p-namespace and c-namespace in together in bean definition( see below):
<?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:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">     
    <bean name="person3" class="com.pfl.samples.spring.cpns.Person" 
         c:_0="Mary" 
         c:_1="Joe" 
         c:_2="30" 
         p:address-ref="address2"/>
</beans> 

You may also have noticed that there is no separate schema definition for p-namespace and c-namespace.

Friday, January 9, 2015

Spring boot Jersey

Part 1 : Spring

Spring boot aims towards simplicity and convention over configuration. First step is to include the necessary configuration in your pom.xml :
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.1.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>http://repo.spring.io/milestone</url>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

One of the good ideas of spring boot is to provide all the 'boilerplate' configuration for you by letting you inherit their parent configuration.
Then, you'll select a starter, in this case, we are going to develop a web application, so starter-web is fine.
Now, we'll create a main function for our application :

@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) throws Exception {
        new SpringApplicationBuilder(Application.class)
                .showBanner(false)
                .run(args);
    }
}

We will just add an index.html file in the webapp directory and we should be ok. With this configuration, you can run the main function and you'll see your index file.

Runnable JAR

Spring boot allows you to package your application as a runnable jar. Include the following in your pom.xml :
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
<pluginRepositories>
    <pluginRepository>
        <id>spring-milestones</id>
        <url>http://repo.spring.io/milestone</url>
    </pluginRepository>
</pluginRepositories>

With this, when running mvn package, you will generate the runnable jar. Just java -jar it to launch an embedded Tomcat containing your webapp !

Part 2: Integrating jersey

Jersey has a spring support project jersey-spring-3. Despite what its name suggests, the project is (still?) compatible with spring 4.0 so we'll use it. It basically allows you to inject spring beans in your jersey controllers.

To complete our configuration we'll add the jersey servlet to our application together with a small class to configure it.

In the Application :
@Bean
public ServletRegistrationBean jerseyServlet() {
    ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), "/rest/*"); 
    // our rest resources will be available in the path /rest/*
    registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
    return registration;
}

We also need to add the @ComponentScan annotation to indicate where our spring services and components can be found (including jersey)
Next, we'll create the JerseyConfig class :
public class JerseyConfig extends ResourceConfig {
    public JerseyConfig() {
        register(RequestContextFilter.class);
        packages("com.geowarin.rest");
        register(LoggingFilter.class);
    }
}

Here we are providing the package(s) in which our rest resources we be located.
Speaking about our rest resources, we'll create a very simple one :

@Path("/")
@Component
public class RestResource {
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/hello")
    public String hello() {
        return "Hello World";
    }
}

There you have it : the dreadful hello world !

= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

Complete Example

In the complete example, I show you how to generate JSON from a domain class.

Basically all you have to do is provide classes with the @XmlRootElement annotation, add the getters and setters for the properties you want serialized and don't forget to provide a default constructor (see here).

To show that dependency injection works, we'll add a very tiny service :
@Singleton
@Service
public class MessageService {
    List<Message> messages = Collections.synchronizedList(new ArrayList<Message>());

    @PostConstruct
    public void init() {
        messages.add(new Message("Joe", "Hello"));
        messages.add(new Message("Jane", "Spring boot is cool !"));
    }

    public List<Message> getMessages() {
        return messages;
    }
}
We can now autowire it to our Jersey controller !
@Path("/")
@Component
public class RestResource {
    @Autowired
    private MessageService messageService;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/messages")
    public List<Message> message() {
        return messageService.getMessages();
    }
}
With moxy in your classpath, it will automatically be converted to JSON.

Testing: Real programmers do tests. We want to test our controller right ? There is a framework for that : jersey-test.

The Problem ? it does not (yet) support annotated configuration.

So, I'm providing a little hack of my own to override the `SpringComponentProvider` class of _jersey-spring3_ and allow this configuration. See the class on github. It is important to place it in the same package as the original one obviously.
Update : I submitted a pull request which has been accepted by Jersey. I updated the project to use the 2.6 snapshot release of jersey which includes the modified SpringComponentProvider.

Now the test :
public class RestResourceTest extends JerseyTest {
    @Override
    protected Application configure() {
        ApplicationContext context = new AnnotationConfigApplicationContext(TestConfig.class);
        return new JerseyConfig().property("contextConfig", context);
    }
    @Test
    public void testHello() {
        final String hello = target("hello").request().get(String.class);
        assertThat(hello).isEqualTo("Hello World");
    }

    @Test
    public void testMessages() throws JSONException {
        final String messages = target("messages").request().get(String.class);
        String expected = "[ " +
                "{ 'author': 'Joe', 'contents': 'Hello'}," +
                "{ 'author': 'Jane', 'contents': 'Spring boot is cool !'}" +
                "]";
        JSONAssert.assertEquals(expected, messages, JSONCompareMode.LENIENT);
    }
}
Jersey Test will automatically select a provider from your classpath, in the example I'm using the in memory provider which I believe to be the fastest but you can also use grizzly and others instead.

I'm using JSONassert to test json results.

In the example, we are providing a very simple, lighter TestConfig :

@Configuration
@ComponentScan(basePackageClasses = RestResource.class)
public class TestConfig {
}
Conclusion

Testing with Jersey Test is fast and intuitive.

Spring boot is a very nice addition to the spring ecosystem. Now that everything should be accessible from the cloud, so should be spring webapps !

References:

Spring Boot
Complete Example

Saturday, September 29, 2012

Maven Repositories

Search Public Maven Artifacts:
http://search.maven.org/
http://download.java.net/maven/2
http://download.java.net/maven/1
http://repo.maven.apache.org/maven2


Spring Framework:
Releases:
<repository>  
  <id>com.springsource.repository.bundles.release</id>  
  <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name>  
  <url>http://repository.springsource.com/maven/bundles/release</url> 
</repository>
...
<dependency>  
  <groupId>org.springframework</groupId>  
  <artifactId>org.springframework.core</artifactId>  
  <version>3.0.2.RELEASE</version> 
</dependency>

Milestone:
<repositories>
 <repository>
  <id>springsource maven repo</id>
  <url>http://maven.springframework.org/milestone</url>
 </repository>
</repositories>
...
<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>3.0.0.RC1</version>
  </dependency>
</dependencies>



Hibernate Framework:
<repositories>
    <repository>
        <id>jboss-public-repository-group</id>
        <name>JBoss Public Maven Repository Group</name>
        <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        <layout>default</layout>
        <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </snapshots>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>jboss-public-repository-group</id>
        <name>JBoss Public Maven Repository Group</name>
        <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        <layout>default</layout>
        <releases>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </releases>
        <snapshots>
            <enabled>true</enabled>
            <updatePolicy>never</updatePolicy>
        </snapshots>
    </pluginRepository>
</pluginRepositories>


Here is the dependency you need:
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.5.4-Final</version>
    </dependency>

Following dependencies is required for slf4j error if you are using hibernate:
<dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.5.6</version>
</dependency>

Wednesday, July 28, 2010

New in Spring 3

Changes in Spring 3

The framework modules have been revised and are now managed separately with one source-tree per module jar:
1. org.springframework.aop
2. org.springframework.beans
3. org.springframework.context
4. org.springframework.context.support
5. org.springframework.expression
6. org.springframework.instrument
7. org.springframework.jdbc
8. org.springframework.jms
9. org.springframework.orm
10. org.springframework.oxm
11. org.springframework.test
12. org.springframework.transaction
13. org.springframework.web
14. org.springframework.web.portlet
15. org.springframework.web.servlet
16. org.springframework.web.struts
Note: The spring.jar artifact that contained almost the entire framework is no longer provided.


We are now using a new Spring build system as known from Spring Web Flow 2.0. This gives us:
1. Ivy-based "Spring Build" system
2. consistent deployment procedure
3. consistent dependency management
4. consistent generation of OSGi manifests


Overview of new Features
This is a list of new features for Spring 3.0. We will cover these features in more detail later in this section.
• Spring Expression Language
• IoC enhancements/Java based bean metadata
• General-purpose type conversion system and field formatting system
• Object to XML mapping functionality (OXM) moved from Spring Web Services project
• Comprehensive REST support
• @MVC additions
• Declarative model validation
• Early support for Java EE 6
• Embedded database support


Core APIs updated for Java 5:
BeanFactory interface returns typed bean instances as far as possible:
• T getBean(Class requiredType)
• T getBean(String name, Class requiredType)
• Map getBeansOfType(Class type)


Spring's TaskExecutor interface now extends java.util.concurrent.Executor.
• extends AsyncTaskExecutor supports standard Callables with Futures.


New Java 5 based converter API and SPI:
• stateless ConversionService and Converters
• superseding standard JDK PropertyEditors
Typed ApplicationListener


Spring Expression Language:
Spring introduces an expression language which is similar to Unified EL in its syntax but offers significantly more features. The expression language can be used when defining XML and Annotation based bean definitions and also serves as the foundation for expression language support across the Spring portfolio.


The Spring Expression Language was created to provide the Spring community a single, well supported expression language that can be used across all the products in the Spring portfolio.


The following is an example of how the Expression Language can be used to configure some properties of a database setup
This functionality is also available if you prefer to configure your components using annotations:
 - - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - -
@Repository
public class RewardsTestDatabase {
   @Value("#{systemProperties.databaseName}")
   public void setDatabaseName(String dbName) { … }
   @Value("#{strategyBean.databaseKeyGenerator}")
    public void setKeyGenerator(KeyGenerator kg) { … }
}
- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - - - -
The Inversion of Control (IoC) container:
• Java based Bean metadata
Some core features from the JavaConfig project have been added to the Spring Framework now. This means that the following annotations are now directly supported:
@Configuration
@Bean
@DependsOn
@Primary
@Lazy
@Import
@ImportResource
@Value
Here is an example of a Java class providing basic configuration using the new JavaConfig features:
- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - - - -
package org.example.config;
@Configuration
public class AppConfig {
   private @Value("#{jdbcProperties.url}") String jdbcUrl;
   private @Value("#{jdbcProperties.username}") String username;
   private @Value("#{jdbcProperties.password}") String password;


   @Bean
   public FooService fooService() {
      return new FooServiceImpl(fooRepository());
   }
   @Bean
   public FooRepository fooRepository() {
      return new HibernateFooRepository(sessionFactory());
   }
   @Bean
   public SessionFactory sessionFactory() {
      // wire up a session factory
      AnnotationSessionFactoryBean asFactoryBean = new AnnotationSessionFactoryBean();
      asFactoryBean.setDataSource(dataSource());
    // additional config
   return asFactoryBean.getObject();
   }
   @Bean
   public DataSource dataSource() {
      return new DriverManagerDataSource(jdbcUrl, username, password);
   }
}
- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - - -
To get this to work you need to add the following component scanning entry in your minimal application context XML file.




Or you can bootstrap a @Configuration class directly using AnnotationConfigApplicationContext:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
public static void main(String[] args) {
   ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
   FooService fooService = ctx.getBean(FooService.class);
   fooService.doStuff();
}
- - - - - - - - - - - - - - - - - - - - - - - - - -- - - - - - - - - - - - - - - - - - -
• Defining bean metadata within components:
@Bean annotated methods are also supported inside Spring components. They contribute a factory bean definition to the container.


• The Data Tier: Object to XML mapping functionality (OXM) from the Spring Web Services project has been moved to the core Spring Framework now


• The Web Tier: The most exciting new feature for the Web Tier is the support for building RESTful web services and web applications. There are also some new annotations that can be used in any web application.
      o Comprehensive REST support:
Server-side support for building RESTful applications has been provided as an extension of the existing annotation driven MVC web framework. Client-side support is provided by the RestTemplate class in the spirit of other template classes such as JdbcTemplate andJmsTemplate. Both server and client side REST functionality make use of HttpConverters to facilitate the conversion between objects and their representation in HTTP requests and responses.
The MarshallingHttpMessageConverter uses the Object to XML mapping functionality mentioned earlier.
    o @MVC additions:
A mvc namespace has been introduced that greatly simplifies Spring MVC configuration.
Additional annotations such as @CookieValue and @RequestHeaders have been added.


• Declarative Model Validation: Several validation enhancements, including JSR 303 support that uses Hibernate Validator as the default provider.


• Early Support for Java EE 6:
We provide support for asynchronous method invocations through the use of the new @Async annotation (or EJB 3.1's @Asynchronous annotation). JSR 303, JSF 2.0, JPA 2.0, etc


• Support for embedded database: Convenient support for embedded Java database engines, including HSQL, H2, and Derby, is now provided.