Introduction Config Example
/* Pro Spring By Rob Harrop Jan Machacek ISBN: 1-59059-461-4 Publisher: Apress */ /////////////////////////////////////////////////////////////////////////////////////// //File: introductions.xml <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean id="beanTarget" class="TargetBean"> <property name="name"> <value>Rob Harrop</value> </property> </bean> </property> <property name="interceptorNames"> <list> <value>advisor</value> </list> </property> <property name="proxyTargetClass"> <value>true</value> </property> </bean> <bean id="advisor" class="IsModifiedAdvisor"/> </beans> /////////////////////////////////////////////////////////////////////////////////////// public interface IsModified { public boolean isModified(); } /////////////////////////////////////////////////////////////////////////////////////// public class TargetBean { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } } /////////////////////////////////////////////////////////////////////////////////////// import org.springframework.aop.support.DefaultIntroductionAdvisor; public class IsModifiedAdvisor extends DefaultIntroductionAdvisor { public IsModifiedAdvisor() { super(new IsModifiedMixin()); } } /////////////////////////////////////////////////////////////////////////////////////// import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.support.DelegatingIntroductionInterceptor; public class IsModifiedMixin extends DelegatingIntroductionInterceptor implements IsModified { private boolean isModified = false; private Map methodCache = new HashMap(); public boolean isModified() { return isModified; } public Object invoke(MethodInvocation invocation) throws Throwable { if (!isModified) { if ((invocation.getMethod().getName().startsWith("set")) && (invocation.getArguments().length == 1)) { // invoke the corresponding get method to see // if the value has actually changed Method getter = getGetter(invocation.getMethod()); if (getter != null) { // modification check is unimportant // for write only methods Object newVal = invocation.getArguments()[0]; Object oldVal = getter.invoke(invocation.getThis(), null); if((newVal == null) && (oldVal == null)) { isModified = false; } else if((newVal == null) && (oldVal != null)) { isModified = true; } else if((newVal != null) && (oldVal == null)) { isModified = true; } else { isModified = (!newVal.equals(oldVal)); } } } } return super.invoke(invocation); } private Method getGetter(Method setter) { Method getter = null; // attempt cache retrieval. getter = (Method) methodCache.get(setter); if (getter != null) { return getter; } String getterName = setter.getName().replaceFirst("set", "get"); try { getter = setter.getDeclaringClass().getMethod(getterName, null); // cache getter synchronized (methodCache) { methodCache.put(setter, getter); } return getter; } catch (NoSuchMethodException ex) { // must be write only return null; } } } /////////////////////////////////////////////////////////////////////////////////////// import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class IntroductionConfigExample { public static void main(String[] args) { ApplicationContext ctx = new FileSystemXmlApplicationContext( "build/introductions.xml"); TargetBean bean = (TargetBean) ctx.getBean("bean"); IsModified mod = (IsModified) bean; // test interfaces System.out.println("Is TargetBean?: " + (bean instanceof TargetBean)); System.out.println("Is IsModified?: " + (bean instanceof IsModified)); // test is modified implementation System.out.println("Has been modified?: " + mod.isModified()); bean.setName("Rob Harrop"); System.out.println("Has been modified?: " + mod.isModified()); bean.setName("Joe Schmoe"); System.out.println("Has been modified?: " + mod.isModified()); } }