In the previous text, I described how to deal with the problem that is described in a post titled pl.comp.lang.java JavaBeans - bad idea using pure AspectJ . Today I'll show how to do the same thing using Spring AOP (remember - it is a notification object for each call PropertyChangeSupport setter for JavaBean'ie).
solution is the most important part of the interceptor, which intercepts calls setter:
pl.kadamczyk.springpropertychange.interceptors package;
import java.lang.reflect.Field;
org.aopalliance.intercept.MethodInterceptor import, import
org.aopalliance.intercept.MethodInvocation;
import pl.kadamczyk.springpropertychange.model.BaseModelObject;
public class SetterMethodInterceptor implements MethodInterceptor
{/ ** *
surrounds the actual method call
* / public Object invoke
(final MethodInvocation method) throws Throwable {String
method.getMethod jointPoint = (). getName ();
/ / Specify the name of the field based on the name induced by setter
String fieldName = jointPoint.replaceFirst ("set", "");
fieldName = Character.toLowerCase (fieldName.charAt (0)) +
fieldName.substring (1);
try {Object target = method.getThis ();
Class clazz = target.getClass ();
/ / grab the box before the scheduled class called
Field field = clazz.getDeclaredField (fieldName);
field.setAccessible (true);
/ / grab the old value Object oldValue
field field.get = (target);
/ / permit Call up setter
method.proceed Object result = ();
if (method.getArguments (). length == 1) {
triggerPropertyChange (target, method.getArguments () [0],
oldValue, fieldName);}
return result;
} catch (NoSuchFieldException e) {throw new RuntimeException
(e);
} catch (IllegalArgumentException e) { throw new RuntimeException
(e);
} catch (IllegalAccessException e) {throw new RuntimeException
(e);
} catch (Throwable e) {throw new RuntimeException
(e);}
} / **
* Checks whether the method was performed on the object class that inherits
* after BaseModelObject, and if so, calls on him firePropertyChange
* / private void
triggerPropertyChange (final Object target, Object newval
final, final Object oldValue, final String fieldName) {
System.out.println ("MethodInterceptor: Change the value of field "
+ fieldName);
if (target instanceof BaseModelObject)
{/ / call the method from the base class
((BaseModelObject) target). firePropertyChange (fieldName, oldValue,
newval);
}}}
This is partly revised version of aspects of the previous post, adjusted to Springowego API.
second step is to configure interceptor:
Noteworthy pointcut.setterAdvisor bean that is responsible for linking the pointcut'ami interceptor where it be applied.
\u0026lt;? Xml version = "1.0" encoding = "UTF-8"?>
\u0026lt;beans xmlns = "http://www.springframework.org/schema/ beans "
xmlns: xsi =" http://www.w3.org/2001/XMLSchema-instance "
xmlns: aop =" http://www.springframework.org/schema/aop "
xmlns: context =" http://www.springframework.org/schema/context "
xsi: schemaLocation ="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring- aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<aop:aspectj-autoproxy />
<bean id="someModelObject"
class="pl.kadamczyk.springpropertychange.model.SomeModelObject"
scope="prototype" />
<bean name="setterInterceptor"
class="pl.kadamczyk.springpropertychange.interceptors.SetterMethodInterceptor" />
<bean name="pointcut.setterAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
\u0026lt;property name="advice" ref="setterInterceptor" />
\u0026lt;property name="mappedName" value="set*" />
\u0026lt;/ bean>
\u0026lt;/ beans>
Unlike the first solution, which used a pure and AspectJ compile-time-weaving, here Applying advice is made in the course of action.
consequence of this is to change how you use the class model. To Spring AOP can generate the appropriate proxy at runtime, you need to download an object from the factory - in our case it will be ClassPathXmlApplicationContext:
Note that the bean someModelObject Spring'a in the configuration file is defined with the attribute scope = "prototype" context.getBean drew to call every time a new instance.
public static void main (final String [] args) {
AbstractApplicationContext context = new ClassPathXmlApplicationContext (
"beans.xml");
SomeModelObject modelObject = (SomeModelObject) context
. getBean ("someModelObject");
modelObject.setSomeIntProperty (23);
modelObject.setSomeStringProperty (ala ');}
As before, the result of the method is main inscription on the console:
MethodInterceptor: Change the value of field someIntProperty
MethodInterceptor: Change the value of field someStringProperty
0 comments:
Post a Comment