Thursday, 18 September 2014

Multiple DataSources with Hibernate - Approach 2

The later versions spring2.0.1 support configure multiple data sources, different data sources and can be loaded dynamically at run time. Can be achieved through inheritance AbstractRoutingDataSource dynamic conversion of multiple data sources. Do project is the need to access the data source, each data source table structure is the same, it requires changes in the data source is transparent for coders, that is to say the same SQL statement that operate in different circumstances The database is not the same. The specific configuration is as follows: You first need to write a static control key class:

      package cn.com.xinli.ccp.dynamicds; 
  
    public   class DataSourceMap { 
     public   static   final String Admin = "Admin"; 
     public   static   final String Yxh = "Yxh"; 
  } 

This class when in use as a data source flag. Second, the establishment of a class to get and set the context:

      public   class CustomerContextHolder { 
         private   static   final ThreadLocal contextHolder = 
                                new ThreadLocal (); 

      public   static   void setCustomerType (String customerType) { 
            contextHolder.set (customerType); 
       } 
      
      public   static String getCustomerType () { 
        return  (String) contextHolder.get (); 
       } 

      public   static   void clearCustomerType () { 
          contextHolder.remove (); 
        }    
    }

This is mainly responsible for setting the context and the context. Third, the establishment of a dynamic data source class, class must inherit AbstractRoutingDataSource

Multiple DataSources with Hibernate - Approach1

The demo application used in the posts mentioned presents how to use a REST API to execute CRUD operations against a back-end db, delivering podcasts. For the demo’s sake I’ll say a client of the REST API also needs resources(podcasts) from a “legacy” system – she needs to combine them with the ones from the actual system and present them to their users. For that I will implement two new read operations that will GET the podcast(s) from the “legacy” system. The new REST facade layer – PodcastLegacyRestService – that delivers “legacy” resources will use the same data access layer to highlight the use of multiple data sources. Now let’s see how to configure and code multiple data sources with Spring and JPA: The first thing I did was to modify the persistence.xml file by adding a new persistence unit that will correspond to the “legacy” entityManager, managing the new “legacy” data source:

persistence.xml

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
                http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
   <persistence-unit name="demoRestPersistence">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
   </persistence-unit>
 
   <persistence-unit name="demoRestPersistenceLegacy">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
   </persistence-unit>   
</persistence>

Note: The persistence unit defines a set of all entity classes that are managed by EntityManager instances in an application. This set of entity classes represents the data contained within a single data store. Because I am using Spring you can see the configuration of the persistence unit in the persistence.xml is very lean. The actual configuration of the entity managers takes places in the Spring’s application context of the application. See the next section for the details.

In the Spring application context I just added new beans for the entity manager, transaction manger and datasource:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.codingpedia.demo.rest.*" />
 
    <!-- ************ JPA configuration *********** -->
    <tx:annotation-driven transaction-manager="transactionManager" />  
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
    <bean id="transactionManagerLegacy" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoryLegacy" />
    </bean>    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:config/persistence-demo.xml" />
        <property name="persistenceUnitName" value="demoRestPersistence" />        
        <property name="dataSource" ref="restDemoDS" />
        <property name="packagesToScan" value="org.codingpedia.demo.*" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
            </bean>
        </property>
    </bean>     
    <bean id="entityManagerFactoryLegacy" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceXmlLocation" value="classpath:config/persistence-demo.xml" />
        <property name="persistenceUnitName" value="demoRestPersistenceLegacy" />
        <property name="dataSource" ref="restDemoLegacyDS" />
        <property name="packagesToScan" value="org.codingpedia.demo.*" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
            </bean>
        </property>
    </bean>  

<bean id="podcastDao" class="org.codingpedia.demo.rest.dao.impl.PodcastDaoJPA2Impl"/>    
    <bean id="podcastRestService" class="org.codingpedia.demo.rest.service.PodcastRestService" />
    <bean id="podcastLegacyRestService" class="org.codingpedia.demo.rest.service.PodcastLegacyRestService" />
 
    <bean id="restDemoDS" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
        <property name="jndiName" value="java:comp/env/jdbc/restDemoDB" />
        <property name="resourceRef" value="true" />        
    </bean>
    <bean id="restDemoLegacyDS" class="org.springframework.jndi.JndiObjectFactoryBean" scope="singleton">
        <property name="jndiName" value="java:comp/env/jdbc/restDemoLegacyDB" />
        <property name="resourceRef" value="true" />        
    </bean>    
</beans>
      

Note the persistenceUnitName property of the entityManagerFactory is pointing to the corresponding persistence unit. Here’s a quick recap of the main configured beans:

  • entityManagerFactoryLegacy (org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean) is a org.springframework.beans.factory.FactoryBean that creates a JPA javax.persistence.EntityManagerFactory according to JPA’s standard container bootstrap contract. This is the most powerful way to set up a shared JPA EntityManagerFactory in a Spring application context; the EntityManagerFactory can then be passed to JPA-based DAOs via dependency injection. Note that switching to a JNDI lookup or to a LocalEntityManagerFactoryBean definition is just a matter of configuration!
    As with LocalEntityManagerFactoryBean, configuration settings are usually read in from a META-INF/persistence.xml config file, residing in the class path, according to the general JPA configuration contract. However, this FactoryBean is more flexible in that you can override the location of the persistence.xml file (as here the case), specify the JDBC DataSources to link to, etc. Furthermore, it allows for pluggable class instrumentation through Spring’s org.springframework.instrument.classloading.LoadTimeWeaver abstraction, instead of being tied to a special VM agent specified on JVM startup. 
  • transactionManagerLegacy (org.springframework.orm.jpa.JpaTransactionManager) is a org.springframework.transaction.PlatformTransactionManager implementation for a single JPA javax.persistence.EntityManagerFactory. Binds a JPA EntityManager from the specified factory to the thread, potentially allowing for one thread-bound EntityManager per factory. SharedEntityManagerCreator and JpaTemplate are aware of thread-bound entity managers and participate in such transactions automatically. Using either is required for JPA access code supporting this transaction management mechanism. This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through org.springframework.transaction.jta.JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.
As mentioned before to highlight the multiple data source configuration in code I extended the DAO layer class with methods to access the “legacy” system:

package org.codingpedia.demo.rest.dao.impl;
 
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
 
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TemporalType;
import javax.persistence.TypedQuery;
 
import org.codingpedia.demo.rest.dao.PodcastDao;
import org.codingpedia.demo.rest.entities.Podcast;
 
public class PodcastDaoJPA2Impl implements PodcastDao {
 
    @PersistenceContext(unitName="demoRestPersistence")
    private EntityManager entityManager;
 
    @PersistenceContext(unitName="demoRestPersistenceLegacy")
    private EntityManager entityManagerLegacy;
 
    public List<Podcast> getPodcasts() {
 
        String qlString = "SELECT p FROM Podcast p";
        TypedQuery<Podcast> query = entityManager.createQuery(
                      qlString, Podcast.class);        
 
        return query.getResultList();
    }
    /* .............................*/
    public List<Podcast> getLegacyPodcasts() {
 
        String qlString = "SELECT p FROM Podcast p";
        TypedQuery<Podcast> query = entityManagerLegacy.createQuery(
                            qlString, Podcast.class);        
 
        return query.getResultList();
    }
 
}

Saturday, 13 September 2014

Hibernate Interceptors


Hibernate Interceptors

The Interceptor interface provides callbacks from the session to the application, allowing the application to inspect and/or manipulate properties of a persistent object before it is saved, updated, deleted or loaded. One possible use for this is to track auditing information. For example, the following Interceptor automatically sets the createTimestamp when an Auditable is created and updates the lastUpdateTimestamp property when an Auditable is updated. You can either implement Interceptor directly or extend EmptyInterceptor.

    
package org.hibernate.test;

import java.io.Serializable;
import java.util.Date;
import java.util.Iterator;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
public class AuditInterceptor extends EmptyInterceptor {
    private int updates;
    private int creates;
    private int loads;
    public void onDelete(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        // do nothing
    }
    public boolean onFlushDirty(Object entity,
        Serializable id,
        Object[] currentState,
        Object[] previousState,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            updates++;
            for (int i = 0; i < propertyNames.length; i++) {
                if ("lastUpdateTimestamp".equals(propertyNames[i])) {
                    currentState[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    public boolean onLoad(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            loads++;
        }
        return false;
    }
    public boolean onSave(Object entity,
        Serializable id,
        Object[] state,
        String[] propertyNames,
        Type[] types) {
        if (entity instanceof Auditable) {
            creates++;
            for (int i = 0; i < propertyNames.length; i++) {
                if ("createTimestamp".equals(propertyNames[i])) {
                    state[i] = new Date();
                    return true;
                }
            }
        }
        return false;
    }
    public void afterTransactionCompletion(Transaction tx) {
        if (tx.wasCommitted()) {
            System.out.println("Creations: " + creates + ", Updates: " + updates, "Loads: " + loads);
        }
        updates = 0;
        creates = 0;
        loads = 0;
    }
}

And here's an explanation of the single callback methods:

Method       Explanation
findDirty      This method is be called when the flush() method is called on a Session object.
instantiate     This method is called when a persisted class is instantiated.
isUnsaved      This method is called when an object is passed to the saveOrUpdate() method/
onDelete      This method is called before an object is deleted.
onFlushDirty     This method is called when Hibernate detects that an object is dirty (ie. have been    
             changed) during a flush i.e. update operation.
onLoad       This method is called before an object is initialized.
onSave       This method is called before an object is saved.
postFlush      This method is called after a flush has occurred and an object has been updated in memory.
preFlush      This method is called before a flush

Saturday, 10 February 2007

Sending a SOAP request to a Web Service via URLConnection


The SOAP request
<?xml version="1.0" encoding="utf-16"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <getUserByEmail xmlns="http://service.w3.ibm.com">
      <iuser>jholy@example.com</iuser>
    </getUserByEmail>
  </soap:Body>
</soap:Envelope>

The Java code


String soapXml = //
java.net.URL url = new java.net.URL("http://localhost:9081/myServiceWAR/services/MyService");
java.net.URLConnection conn = url.openConnection();

// Set the necessary header fields
conn.setRequestProperty("SOAPAction", "http://localhost:9081/myServiceWAR/services/MyService");
conn.setDoOutput(true);

// Send the request
java.io.OutputStreamWriter wr = new java.io.OutputStreamWriter(conn.getOutputStream());
wr.write(soapXml);
wr.flush();

// Read the response
java.io.BufferedReader rd = new java.io.BufferedReader(
new java.io.InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null) {
System.out.println(line);
}

Friday, 2 February 2007

Java Annotations

What are Java Annotations?

Annotations is a new feature from Java 5. Annotations are a kind of comment or meta data you can insert in your Java code. These annotations can then be processed at compile time by pre-compiler tools, or at runtime via Java Reflection. Here is an example of class annotation:

@MyAnnotation(name="someName",  value = "Hello World")
public class TheClass { }

The class TheClass has the annotation @MyAnnotation written ontop. Annotations are defined like interfaces. Here is the MyAnnotation definition:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

public @interface MyAnnotation {
    public String name();
    public String value();
}

The @ in front of the interface marks it as an annotation. Once you have defined the annotation you can use it in your code, as shown in the earlier examples. The two directives in the annotation definition, @Retention(RetentionPolicy.RUNTIME) and@Target(ElementType.TYPE), specifies how the annotation is to be used.

  • @Retention(RetentionPolicy.RUNTIME) means that the annotation can be accessed via reflection at runtime. If you do not set this directive, the annotation will not be preserved at runtime, and thus not available via reflection.
  • @Target(ElementType.TYPE) means that the annotation can only be used ontop of types (classes and interfaces typically). You can also specify METHOD or FIELD, or you can leave the target out alltogether so the annotation can be used for both classes, methods and fields.


An annotation need to have a RetentionPolicy that will be the scope of the annotation where at this point the annotation will be ignored or discarded. The values are RetentionPolicy.SOURCE,RetentionPolicy.CLASS and RetentionPolicy.RUNTIME. When no retention policy defined it will use the default retention policy which is the RetentionPolicy.CLASS.

Annotation with SOURCE retention policy will be retained only in the source code, it available to the compiler when it compiles the class and will be discarded after that. The CLASS retention policy will make the annotation stored in the class file during compilation, but will not available during the runtime. And the RUNTIME retention policy will stored the annotation in the class file during compilation and it also available to JVM at runtime.

All annotations are extending the java.lang.annotation.Annotation interface, which means that java.lang.annotation.Annotation is the super-interface of all annotations.

Class Annotations

You can access the annotations of a class, method or field at runtime. Here is an example that accesses the class annotations:

Class aClass = TheClass.class;
Annotation[] annotations = aClass.getAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

You can also access a specific class annotation like this:

Class aClass = TheClass.class;
Annotation annotation = aClass.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

 

Method Annotations

Here is an example of a method with annotations:

public class TheClass {
  @MyAnnotation(name="someName",  value = "Hello World")
  public void doSomething(){}
}

You can access method annotations like this:

Method method = ... //obtain method object
Annotation[] annotations = method.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}

You can also access a specific method annotation like this:

Method method = ... // obtain method object
Annotation annotation = method.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Parameter Annotations

It is possible to add annotations to method parameter declarations too. Here is how that looks:

public class TheClass {
  public static void doSomethingElse(
        @MyAnnotation(name="aName", value="aValue"String parameter){
  }
}

You can access parameter annotations from the Method object like this:

Method method = ... //obtain method object
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
Class[] parameterTypes = method.getParameterTypes();

int i=0;
for(Annotation[] annotations : parameterAnnotations){
  Class parameterType = parameterTypes[i++];

  for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("param: " + parameterType.getName());
        System.out.println("name : " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
  }
}

Notice how the Method.getParameterAnnotations() method returns a two-dimensional Annotation array, containing an array of annotations for each method parameter.

Field Annotations

Here is an example of a field with annotations:


public class TheClass {

  @MyAnnotation(name="someName",  value = "Hello World")
  public String myField = null;
}

You can access field annotations like this:

Field field = ... //obtain field object
Annotation[] annotations = field.getDeclaredAnnotations();

for(Annotation annotation : annotations){
    if(annotation instanceof MyAnnotation){
        MyAnnotation myAnnotation = (MyAnnotationannotation;
        System.out.println("name: " + myAnnotation.name());
        System.out.println("value: " + myAnnotation.value());
    }
}
Field field = ... // obtain method object
Annotation annotation = field.getAnnotation(MyAnnotation.class);

if(annotation instanceof MyAnnotation){
    MyAnnotation myAnnotation = (MyAnnotationannotation;
    System.out.println("name: " + myAnnotation.name());
    System.out.println("value: " + myAnnotation.value());
}

Wednesday, 17 January 2007

Java Dynamic Proxies: One Step from Aspect-oriented Programming

Dynamic Proxies are a nifty, often overlooked feature of the Java language. Introduced in J2SE 1.3, they allow you to intercept method calls so you can interpose additional behavior between a class caller and its"callee". From the caller's perspective, a proxy is no different from the real class that it encapsulates — it presents the same interfaces and follows all the rules and conventions expected of the real class. For savvy programmers, proxies present a unique time saving opportunity. Why spend effort inserting and maintaining such common code as debugging and logging when you can just centralize it and put in a proxy instead? Logging, retry semantics,performance metrics, performance optimizations, test stubs, and caching are examples of application concerns that cut across class implementations regardless of design and business function. Trends within the Java community are modeling such concerns as aspects—important to the application but orthogonal to the main task at hand. Rather than coding this logic painstakingly throughout your application, wouldn't it be nice if you could just express this behavior in one place and have it apply to every class? With Dynamic proxies, you can easily do so—and once youunderstand proxies, you've made a small conceptual leap towards the bigger picture—aspect-oriented programming (AOP).

Dynamic Proxy Basics
A dynamic proxy is a class that implements a list of interfaces, which you specify at runtime when you create the proxy. To create a proxy, use the static method java.lang.reflect.Proxy.newP
roxyInstance().This method takes three arguments:

  • The class loader to define the proxy class
  • An invocation handler to intercept and handle method calls
  • A list of interfaces that the proxy instance implements
The returned Proxy instance behaves like any other class that implements the supplied interfaces. The statement, proxy instanceof MyInterface, returns true and casts to any of the target interfaces. For example,
MyInterface obj = (MyInterface) proxy
will also succeed.

From the code perspective, the proxy instance is no different from a normal class. Provided the actual creation of the proxy is encapsulated (e.g., inside a factory or ServiceLocator), the proxy is totally transparent. Behavior can be inserted dynamically without changing the way your classes are wired or how your code interacts. This transparency enables you to add common code easily and quickly without affecting class collaborations or having to add (or test) your extra code explicitly for every class.

At the heart of the Proxy mechanism is the InvocationHandler interface. You must supply an InvocationHandler instance when you create a proxy instance. The InvocationHandler is responsible for intercepting and dispatching all method calls made on the proxy. It contains one method: invoke(Object proxy, Method method, Object[] args). The first argument is the proxy instance that has been invoked, the second argument is the target method, and the third argument (args) are the runtime parameters that the caller supplies. You must add any additional behavior inside the invoke() method, as this will get executed whenever a method is executed on the proxy.

Take a common cross cutting concern, logging, as an example. Create a simple InvocationHandler class that logs method entries and exits using System.out.println. Your class must implement the InvocationHandler interface and provide an implementation of the invoke() method. Pass the real class inas a parameter on the constructor, as follows:

public class LoggingHandler implements InvocationHandler {
    protected Object delegate;

    public LoggingHandler(Object delegate) { 
         this.delegate = delegate; 
    }

    public Object invoke(Object proxy,Method method,
                   Object[] args) throws Throwable {
        try {
            System.out.println("Calling method "+ method+ " at "
                + System.currentTimeMillis());
            Object result = method.invoke(delegate, args);
            return result;
         } catch (InvocationTargetException e) {
             throw e.getTargetException();
         } finally {
             System.out.println("Called method("+ method+ " at "
                + System.currentTimeMillis());
         }
      }
}

Monday, 15 January 2007

Proxy Pattern & Dynamic Proxies

B) Dynamic Proxies

Using Java Reflection you create dynamic implementations of interfaces at runtime. You do so using the class java.lang.reflect.Proxy.The name of this class is why I refer to these dynamic interface implementations as dynamic proxies. Dynamic proxies can be used for many different purposes, e.g.database connection and transaction management,dynamic mock objects for unit testing, and other AOP-like method intercepting purposes. Here is a list of topics covered in this post on dynamic proxies:

  1. Creating Proxies
  2. InvocationHandler's
  3. Known Use Cases

B.1)Creating Proxies
You create dynamic proxies using the "Proxy.newProxyInstance()" method. The newProxyInstance() methods takes 3 parameters:

  1. The ClassLoader that is to "load" the dynamic proxy class.
  2. An array of interfaces to implement.
  3. An InvocationHandler to forward all methods calls on the proxy to.

Here is an example:

InvocationHandler handler = new MyInvocationHandler();
MyInterface proxy = (MyInterface)
Proxy.newProxyInstance(
MyInterface.class.getClassLoader(),
new Class[]{ MyInterface.class },
handler);

After running this code the proxy variable contains a dynamic implementation of the MyInterface interface.All calls to the proxy will be forwarded to the handler implementation of the general InvocationHandler interface.InvocationHandler's are covered in the next section.

B.2)InvocationHandler's 

As mentioned earlier you must pass an InvocationHandler implementation to the Proxy.newProxyIn stance() method. All method calls to the dynamic proxy are forwarded to this InvocationHandler implementation.Here is how the InvocationHandler interface looks:


public interface InvocationHandler{
Object invoke(Object proxy,
Method method, Object[] args) throws Throwable;
}

Example implementation

public class MyInvocationHandler
implements InvocationHandler{
public Object invoke(Object proxy,
Method method, Object[] args) throws Throwable {
//do something "dynamic"
}
}

The proxy parameter passed to the invoke() method is the dynamic proxy object implementing the interface.Most often you don't need this object.The Method object passed into the invoke() method represents the method called on the interface the dynamic proxy implements.From the Method object you can obtain the method name, parameter types, return type, etc.See the text on 'Methods' for more information.The Object[] args array contains the parameter values passed to the proxy when the method in the interface implemented was called.

Note:
Primitives (int, long etc) in the implemented interface arewrapped in their object counterpars (Integer, Long etc.).

B.3)Known Use Cases
Dynamic proxies are known to be used for at least the following purposes:

  1. Database Connection and Transaction Management
  2. Dynamic Mock Objects for Unit Testing
  3. Adaptation of DI Container to Custom Factory Interfaces
  4. AOP-like Method Interception

B.3.1)Database Connection and Transaction Management
The Spring framework has a transaction proxy that can start and commit / rollback a transaction for you.This use case will be explained in more detail in the next text in this Java Reflection series, so I'll only describe it briefly. The call sequence becomes something along this:
web controller --> proxy.execute(...);
proxy --> connection.setAutoCommit(false);
proxy --> realAction.execute();
real Action does database work
proxy --> connection.commit();

B.3.2)Dynamic Mock Objects for Unit Testing
The Butterfly Testing Tools makes use of dynamic proxies to implement dynamic stubs,mocks and proxies for unit testing. When testing a class A that uses another class B (interface really), you can pass a mock implementation of B into A instead of a real B. All method calls on B are now recorded, and you can set what return values the mock B is to return. Furthermore Butterfly Testing Tools allow you to wrap a real B in a mock B,so that all method calls on the mock are recorded, and then forwarded to the real B. This makes it possible to check what methods were called on a real functioning B. For instance,if testing a DAO you can wrap the database connection in a mock. The DAO will not see the difference,and the DAO can read/write data to the database as usual since the mock forwards all calls to the database. But now you can check via the mock if the DAO uses theconnection properly, for instance if the connection.close() is called (or NOT called), if you expected that.This is normally not possible to determine from the return value of a DAO.

B.3.3)Adaptation of DI Container to Custom Factory Interfaces
The dependency injection container Butterfly Container has a powerful feature that allows you to inject thewhole container into beans produced by it. But, since you don't want a dependency on the container interface, the container is capable of adapting itself to a custom factory interface of your design. You onlyneed the interface. No implementation. Thus the factory interface and your class could look something like this:

public interface IMyFactory {
Bean bean1();
Person person();
...
}

public class MyAction{
protected IMyFactory myFactory= null;
public MyAction(IMyFactory factory){
this.myFactory = factory;
}
public void execute(){
Bean bean = this.myFactory.bean();
Person person = this.myFactory.person();
}
}

When the MyAction class calls methods on the IMyFactory instance injected into its constructor by the container, the method calls are translated into calls to the IContainer.instance() method, which is the method you use to obtain instances from the container. That way an object can use Butterfly Container asa factory at runtime, rather than only to have dependencies injected into itself at creation time. And this without having any dependencies on any Butterfly Container specific interfaces.

B.3.4)AOP-like Method Interception
The Spring framework makes it possible to intercept method calls to a given bean, provided that beanimplements some interface. The Spring framework wraps the bean in a dynamic proxy. All calls to thebean are then intercepted by the proxy. The proxy can decide to call other methods on other objects eitherbefore, instead of, or after delegating the method call to the beean wrapped.