
Code sample is below, you can download eclipse project as .rar file from here.
Package Structure

package client; import proxypattern.IService; import proxypattern.ServiceProxy; public class Main { public static void main (String[] args) { IService service = new ServiceProxy(); service.method1(); } }
package proxypattern.authorization; import proxypattern.User; public class AuthorizationService implements IAuthorizationService { public boolean isUserAuthorizedToCallServiceMethod (String methodName, User user) { System.out.println(user + " has access rights to do " + methodName); return true; } }
package proxypattern.authorization; import proxypattern.User; public interface IAuthorizationService { boolean isUserAuthorizedToCallServiceMethod (String methodName, User user); }
package proxypattern.log; public interface ILogService { void log (String log); }
package proxypattern.log; public class LogService implements ILogService { public void log (String log) { System.out.println(log); } }
package proxypattern.transaction; public interface ITransactionService { Session getSession (); }
package proxypattern.transaction; public class Session { public void beginTransaction () { System.out.println("transaction started."); } public void close () { System.out.println("session closed."); } public void commit () { System.out.println("transaction committed."); } public void executeQuery (String query) { System.out.println(query + " executed."); } public void open () { System.out.println("session opened."); } public void rollback () { System.out.println("transaction rollbacked."); } }
package proxypattern.transaction; public class TransactionService implements ITransactionService { public Session getSession () { return new Session(); // for example you can use hibernate session factory to get a session. } }
package proxypattern; import proxypattern.authorization.AuthorizationService; import proxypattern.authorization.IAuthorizationService; import proxypattern.log.ILogService; import proxypattern.log.LogService; import proxypattern.transaction.ITransactionService; import proxypattern.transaction.Session; import proxypattern.transaction.TransactionService; // this class is used for all cross cut concerns such as authorization, log, transaction. abstract class AbstractServiceMethodCall { private ILogService logService = new LogService(); private IAuthorizationService authorizatiService = new AuthorizationService(); private ITransactionService transactionService = new TransactionService(); protected Session session; public void afterDelegation (String methodName, User user) { this.session.commit(); this.session.close(); this.logService.log(methodName + " operation complete successfully"); } public void beforeDelegation (String methodName, User user) throws IllegalAccessException { this.logService.log(methodName + " is called by " + user.toString()); if (!this.authorizatiService.isUserAuthorizedToCallServiceMethod(methodName, user)) { throw new IllegalAccessException(); } this.session = this.transactionService.getSession(); this.session.open(); this.session.beginTransaction(); } public void executeOperation (String methodName, User user) { try { this.beforeDelegation("method1", user); this.serviceOperation(this.session); this.afterDelegation("method1", user); } catch (IllegalAccessException e) { this.operationFailed("method1", user); } } public void operationFailed (String string, User user) { this.session.rollback(); this.session.close(); } public abstract void serviceOperation (Session session); }
package proxypattern; class ServiceImp implements IService { public void method1 () { System.out.println("method1 of " + this.getClass().getSimpleName() + " called."); } }
package proxypattern; import proxypattern.transaction.Session; // this class is not thread safe you have to create a new instance before using public class ServiceProxy implements IService { private IService delegated = new ServiceImp(); public void method1 () { new AbstractServiceMethodCall() { @Override public void serviceOperation (Session session) { ServiceProxy.this.delegated.method1(); } }.executeOperation("method1", new User()); } }
package proxypattern; public class User { @Override public String toString () { return "userId"; } }As you can see in ServiceProxy .java we add log, authorization and transaction operations before and after actual service method call.
Output :
method1 is called by userId //log service
userId has access rights to do method1 //authorization service
session opened. //transaction service
transaction started. //transaction service
method1 of ServiceImp called. //actual service call service
transaction committed. //transaction service
session closed. //transaction service
method1 operation complete successfully //log service