Java/Spring/AOP
Содержание
- 1 Annotated Autowiring
- 2 Annotation Component
- 3 Annotation Scope
- 4 AOP Annotation
- 5 Aspect Annotation
- 6 Aspect Annotation Pointcut AroundAfter
- 7 Aspect Filter
- 8 AspectJ AutoProxy
- 9 AspectJ Expression Pointcut
- 10 ComposablePointcut Intersection
- 11 ComposablePointcut Union
- 12 Concurrency Throttle Interceptor
- 13 Customizable TraceInterceptor
- 14 Jdk Regexp Method Pointcut
- 15 Matcher For Getter And Setter
- 16 Method Lookup
- 17 Spring AOP Examples
- 18 Spring Tracing Aspect
Annotated Autowiring
<source lang="java">
File: context.xml <?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="a" class="A"/> <bean id="b" class="B"/> <bean id="annotatedTarget" class="AnnotatedClass"/> <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>
File: Main.java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] args) { ApplicationContext bf = new ClassPathXmlApplicationContext("context.xml"); System.out.println("annotatedTarget:"); System.out.println(bf.getBean("annotatedTarget"));
}
} class A {
@Override public String toString() { return getClass().getName(); }
} class B {
@Override public String toString() { return getClass().getName(); }
} class AnnotatedClass {
@Autowired private A foo; @Autowired private A foo2; @Autowired private B bar; @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("AnnotatedClass"); sb.append("{foo=").append(foo); sb.append(", foo2=").append(foo2); sb.append(", bar=").append(bar); sb.append("}"); return sb.toString(); }
}
</source>
Annotation Component
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="bean"> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> </context:component-scan>
</beans>
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import bean.Helper; import bean.HelperDemo; public class Main {
public static void main(String[] args) throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext( "context.xml"); HelperDemo hd1 = (HelperDemo) ac.getBean("helperDemo"); hd1.someOperation(); System.out.println(hd1); HelperDemo hd2 = (HelperDemo) ac.getBean("helperDemo"); hd2.someOperation(); System.out.println(hd2); Helper helper = (Helper) ac.getBean("helper"); System.out.println(helper); }
} File: Helper.java package bean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component("helper") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class Helper {
private int count; public void work() { this.count++; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Helper"); sb.append("{count=").append(count); sb.append("}"); return sb.toString(); }
}
File: HelperDemo.java package bean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class HelperDemo {
@Autowired private Helper helper; public void setHelper(Helper helper) { this.helper = helper; } public void someOperation() { this.helper.work(); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("HelperDemo"); sb.append("{helper=").append(helper); sb.append("}"); return sb.toString(); }
}
</source>
Annotation Scope
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="bean"> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> </context:component-scan>
</beans>
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import bean.Helper; import bean.HelperDemo; public class Main {
public static void main(String[] args) throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext( "context.xml"); HelperDemo hd1 = (HelperDemo) ac.getBean("helperDemo"); hd1.someOperation(); System.out.println(hd1); HelperDemo hd2 = (HelperDemo) ac.getBean("helperDemo"); hd2.someOperation(); System.out.println(hd2); Helper helper = (Helper) ac.getBean("helper"); System.out.println(helper); }
} File: Helper.java package bean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component("helper") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class Helper {
private int count; public void work() { this.count++; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Helper"); sb.append("{count=").append(count); sb.append("}"); return sb.toString(); }
}
File: HelperDemo.java package bean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class HelperDemo {
@Autowired private Helper helper; public void setHelper(Helper helper) { this.helper = helper; } public void someOperation() { this.helper.work(); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("HelperDemo"); sb.append("{helper=").append(helper); sb.append("}"); return sb.toString(); }
}
</source>
AOP Annotation
<source lang="java">
File: Main.java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Method; import org.springframework.aop.Advisor; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.annotation.AnnotationMatchingPointcut; public class Main {
public static void main(String[] args) { SampleBean target = new SampleBean(); AnnotationMatchingPointcut pc = new AnnotationMatchingPointcut(null, SimpleAnnotation.class); Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); SampleBean proxy = (SampleBean) pf.getProxy(); proxy.getName(); proxy.getHeight(); }
} class SimpleBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("Before method " + method); }
} @SimpleAnnotation class SampleBean {
@SimpleAnnotation public String getName() { return "AAA"; } public void setName(String name) { } public int getHeight() { return 201; }
} @Target( { ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @interface SimpleAnnotation { } class AnnotationAfterAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.print("After annotated method: " + method); }
}
</source>
Aspect Annotation
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <aop:aspectj-autoproxy /> <context:component-scan base-package="bean"> <context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/> </context:component-scan>
</beans>
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import bean.Helper; import bean.HelperDemo; public class Main {
public static void main(String[] args) throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext( "context.xml"); HelperDemo hd1 = (HelperDemo) ac.getBean("helperDemo"); hd1.someOperation(); System.out.println(hd1); HelperDemo hd2 = (HelperDemo) ac.getBean("helperDemo"); hd2.someOperation(); System.out.println(hd2); Helper helper = (Helper) ac.getBean("helper"); System.out.println(helper); }
} File: Helper.java package bean; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component("helper") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class Helper {
private int count; public void work() { this.count++; } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("Helper"); sb.append("{count=").append(count); sb.append("}"); return sb.toString(); }
}
File: HelperDemo.java package bean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.ruponent; @Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class HelperDemo {
@Autowired private Helper helper; public void setHelper(Helper helper) { this.helper = helper; } public void someOperation() { this.helper.work(); } @Override public String toString() { final StringBuilder sb = new StringBuilder(); sb.append("HelperDemo"); sb.append("{helper=").append(helper); sb.append("}"); return sb.toString(); }
}
</source>
Aspect Annotation Pointcut AroundAfter
<source lang="java">
File: context.xml <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="test" class="TestBean"/> <bean class="LoggingAspectPC"> <property name="beforeMessage" value="Before %s %s"/> <property name="afterMessage" value="After %s %s"/> </bean> <aop:aspectj-autoproxy />
</beans>
File: Main.java import java.util.Arrays; import javax.annotation.PostConstruct; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("context.xml"); TestBean testBean = (TestBean) ac.getBean("test"); testBean.work(); testBean.stop(); }
} class TestBean {
public void work() { System.out.println("work"); } public void stop() { System.out.println("stop"); }
} @Aspect
class LoggingAspectPC { private String beforeMessage; private String afterMessage; @Pointcut("execution(* TestBean.*(..))") private void testBeanExecution() { } @Around("testBeanExecution()") public Object log(ProceedingJoinPoint pjp) throws Throwable { System.out.println(this.beforeMessage); System.out.println(pjp.getSignature().getName()); System.out.println(Arrays.toString(pjp.getArgs())); Object ret = pjp.proceed(); System.out.println(this.afterMessage); System.out.println(pjp.getSignature().getName()); System.out.println(Arrays.toString(pjp.getArgs())); return ret; } @After("testBeanExecution()") public void afterCall(JoinPoint jp) { System.out.println("After"); } @PostConstruct public void initialize() { System.out.println("initialize:"+this.beforeMessage); System.out.println("initialize:"+this.afterMessage); } public void setBeforeMessage(String beforeMessage) { this.beforeMessage = beforeMessage; } public void setAfterMessage(String afterMessage) { this.afterMessage = afterMessage; }
}
</source>
Aspect Filter
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="bean"> <context:include-filter type="annotation" expression="bean.Magic"/> <context:include-filter type="assignable" expression="bean.ruponentMarker"/> <context:include-filter type="aspectj" expression="* void bean.*Service*(..)"/> </context:component-scan>
</beans>
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] args) throws Exception { ApplicationContext ac = new ClassPathXmlApplicationContext( "context.xml"); String[] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName + ": " + ac.getBean(beanName)); } }
}
</source>
AspectJ AutoProxy
<source lang="java">
File: context.xml <?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="test" class="TestBean2"> <property name="simpleBean" ref="simple"/> </bean> <bean id="simple" class="SimpleBean"/> <bean class="Main"/> <aop:aspectj-autoproxy/>
</beans>
File: Main.java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main {
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("context.xml"); TestBean2 testBean = (TestBean2) ac.getBean("test"); SimpleBean simpleBean = (SimpleBean) ac.getBean("simple"); testBean.work(); testBean.stop(); simpleBean.sayHello(); simpleBean.x("a", "b"); }
} class TestBean2 {
private SimpleBean simpleBean; public void work() { this.simpleBean.sayHello(); System.out.println("work"); } public void stop() { this.simpleBean.sayHello(); System.out.println("stop"); } public void setSimpleBean(SimpleBean simpleBean) { this.simpleBean = simpleBean; }
} class SimpleBean {
public void sayHello() { System.out.println("Hello"); } public void x(CharSequence a, String b) { }
}
</source>
AspectJ Expression Pointcut
<source lang="java">
File: Main.java import org.springframework.aop.Advisor; import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import bean.MyClass; import bean.SimpleAfterAdvice; public class Main {
public static void main(String[] args) { MyClass target = new MyClass(); AspectJExpressionPointcut pc = new AspectJExpressionPointcut(); pc.setExpression("execution(* bean..*.get*(..))"); Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleAfterAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); MyClass proxy = (MyClass) pf.getProxy(); System.out.println(proxy.getName()); proxy.setName("New Name"); System.out.println(proxy.getHeight()); }
} File: MyClass.java package bean;
public class MyClass {
public String getName() { return "AAA"; } public void setName(String name) { } public int getHeight() { return 201; }
}
File: SimpleAfterAdvice.java package bean; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method;
public class SimpleAfterAdvice implements AfterReturningAdvice{
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("After method: " + method); }
}
</source>
ComposablePointcut Intersection
<source lang="java">
File: Main.java import java.lang.reflect.Method; import org.springframework.aop.Advisor; import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.ruposablePointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.StaticMethodMatcher; public class Main {
public static void main(String[] args) { SampleBean target = new SampleBean(); ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, new GetterMethodMatcher());
pc.intersection(new GetAgeMethodMatcher()); SampleBean proxy = getProxy(pc, target); testInvoke(proxy); } private static SampleBean getProxy(ComposablePointcut pc, SampleBean target) { Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); return (SampleBean) pf.getProxy(); } private static void testInvoke(SampleBean proxy) { proxy.getAge(); proxy.getName(); proxy.setName("QQQ"); }
} class GetterMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return (method.getName().startsWith("get")); }
}
class GetAgeMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return "getAge".equals(method.getName()); }
} class SampleBean {
public String getName() { return "AAA"; } public void setName(String name) { } public int getAge() { return 100; }
} class SimpleBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("Before method " + method); }
}
</source>
ComposablePointcut Union
<source lang="java">
File: Main.java import java.lang.reflect.Method; import org.springframework.aop.Advisor; import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.ruposablePointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.StaticMethodMatcher; public class Main {
public static void main(String[] args) { SampleBean target = new SampleBean(); ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, new GetterMethodMatcher());
pc.union(new SetterMethodMatcher()); SampleBean proxy = getProxy(pc, target); testInvoke(proxy); } private static SampleBean getProxy(ComposablePointcut pc, SampleBean target) { Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); return (SampleBean) pf.getProxy(); } private static void testInvoke(SampleBean proxy) { proxy.getAge(); proxy.getName(); proxy.setName("QQQ"); }
} class GetterMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return (method.getName().startsWith("get")); }
} class SetterMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return (method.getName().startsWith("set")); }
} class SampleBean {
public String getName() { return "AAA"; } public void setName(String name) { } public int getAge() { return 100; }
} class SimpleBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("Before method " + method); }
}
</source>
Concurrency Throttle Interceptor
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="afterBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="MtBean"> <property name="firstName" value="AAA"/> </bean> </property> <property name="interceptorNames"> <list> <idref bean="endMatchPointcutAdvisor"/> </list> </property> <property name="proxyTargetClass" value="true"/> </bean> <bean id="endMatchPointcutAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor" singleton="false"> <property name="advice" ref="concurrencyThrottleInterceptor"/> <property name="mappedName" value="showValues"/> </bean> <bean id="concurrencyThrottleInterceptor" class="org.springframework.aop.interceptor.ConcurrencyThrottleInterceptor" singleton="false"> <property name="concurrencyLimit" value="5"/> </bean>
</beans>
File: Main.java import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.util.StopWatch; public class Main {
public static void main(String[] args) throws Exception { BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("context.xml")); MtBean testBean = (MtBean) beanFactory .getBean("afterBean"); testBean.showValues(); }
} class MtBean {
private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void showValues() { System.out.println("First name: " + this.firstName); }
}
</source>
Customizable TraceInterceptor
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="afterBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="MtBean"> <property name="firstName" value="AAA"/> </bean> </property> <property name="interceptorNames"> <list> <idref bean="traceInterceptor"/> </list> </property> <property name="proxyTargetClass" value="true"/> </bean> <bean id="traceInterceptor" class="org.springframework.aop.interceptor.CustomizableTraceInterceptor"> <property name="enterMessage" value="Entered $[methodName] on $[targetClassShortName]"/> </bean>
</beans>
File: Main.java import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; import org.springframework.util.StopWatch; public class Main {
public static void main(String[] args) throws Exception { BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("context.xml")); MtBean testBean = (MtBean) beanFactory .getBean("afterBean"); testBean.showValues(); }
} class MtBean {
private String firstName; public String getFirstName() { return this.firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public void showValues() { System.out.println("First name: " + this.firstName); }
}
</source>
Jdk Regexp Method Pointcut
<source lang="java">
File: Main.java import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.Advisor; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.JdkRegexpMethodPointcut; public class Main {
public static void main(String[] args) { RegexpBean target = new RegexpBean(); JdkRegexpMethodPointcut pc = new JdkRegexpMethodPointcut(); pc.setPattern(".*foo.*"); Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); RegexpBean proxy = (RegexpBean)pf.getProxy(); proxy.foo1(); proxy.foo2(); proxy.bar(); }
} class SimpleAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("SimpleAdvice.Invoking:" + invocation.getMethod().getName()); Object retVal = invocation.proceed(); System.out.println("SimpleAdvice.Done"); return retVal; }
} class RegexpBean {
public void foo1() { System.out.println("RegexpBean.foo1"); } public void foo2() { System.out.println("RegexpBean.foo2"); } public void bar() { System.out.println("RegexpBean.bar"); }
}
</source>
Matcher For Getter And Setter
<source lang="java">
File: Main.java import java.lang.reflect.Method; import org.springframework.aop.Advisor; import org.springframework.aop.ClassFilter; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.ruposablePointcut; import org.springframework.aop.support.DefaultPointcutAdvisor; import org.springframework.aop.support.StaticMethodMatcher; public class Main {
public static void main(String[] args) { SampleBean target = new SampleBean(); ComposablePointcut pc = new ComposablePointcut(ClassFilter.TRUE, new GetterMethodMatcher());
pc.union(new SetterMethodMatcher()); SampleBean proxy = getProxy(pc, target); testInvoke(proxy); } private static SampleBean getProxy(ComposablePointcut pc, SampleBean target) { Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleBeforeAdvice()); ProxyFactory pf = new ProxyFactory(); pf.setTarget(target); pf.addAdvisor(advisor); return (SampleBean) pf.getProxy(); } private static void testInvoke(SampleBean proxy) { proxy.getAge(); proxy.getName(); proxy.setName("QQQ"); }
} class GetterMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return (method.getName().startsWith("get")); }
} class SetterMethodMatcher extends StaticMethodMatcher {
public boolean matches(Method method, Class cls) { return (method.getName().startsWith("set")); }
} class SampleBean {
public String getName() { return "AAA"; } public void setName(String name) { } public int getAge() { return 100; }
} class SimpleBeforeAdvice implements MethodBeforeAdvice {
public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("Before method " + method); }
}
</source>
Method Lookup
<source lang="java">
File: context.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataService" class="DataServiceImpl"> <lookup-method name="getDataDao" bean="dataDao"/> </bean> <bean id="dataDao" singleton="false" class="StatefulDataDataDaoImpl"> </bean>
</beans>
File: Main.java import java.util.Date; import java.util.GregorianCalendar; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; class Main {
public static void main(String args[]) throws Exception { ApplicationContext ctx = new ClassPathXmlApplicationContext( "context.xml"); DataService ws = (DataService) ctx.getBean("dataService"); Double high = ws.getHistoricalHigh(new GregorianCalendar(2004, 0, 1).getTime()); System.out.println("High was: " + high); ws = new DataServiceImpl() { protected DataDao getDataDao() { return null; } }; }
} abstract class DataServiceImpl implements DataService {
protected abstract DataDao getDataDao(); public Double getHistoricalHigh(Date date) { DataData wd = getDataDao().find(date); if (wd != null) return new Double(wd.getHigh()); return null; }
} interface DataService {
Double getHistoricalHigh(Date date);
} class DataData {
Date date; double low; double high; public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } public double getLow() { return low; } public void setLow(double low) { this.low = low; } public double getHigh() { return high; } public void setHigh(double high) { this.high = high; }
} interface DataDao {
DataData find(Date date); DataData save(Date date); DataData update(Date date);
} class StatefulDataDataDaoImpl implements DataDao {
public DataData find(Date date) { DataData wd = new DataData(); wd.setDate((Date) date.clone()); wd.setLow(5); wd.setHigh(15); return wd; } public DataData save(Date date) { throw new UnsupportedOperationException("This class uses static data only"); } public DataData update(Date date) { throw new UnsupportedOperationException("This class uses static data only"); }
}
</source>
Spring AOP Examples
Spring Tracing Aspect
<source lang="java">
File: IBusinessLogic.java
public interface IBusinessLogic {
public void foo();
}
File: MainApplication.java
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApplication {
public static void main(String [] args) { ApplicationContext ctx = new FileSystemXmlApplicationContext("build/springconfig.xml"); IBusinessLogic testObject = (IBusinessLogic) ctx.getBean("businesslogicbean"); testObject.foo(); }
}
File: springconfig.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>
<bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> <property name="interceptorNames"> <list> <value>theTracingBeforeAdvisor</value> <value>theTracingAfterAdvisor</value> </list> </property> </bean> <bean id="beanTarget" class="BusinessLogic"/> <bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingBeforeAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean> <bean id="theTracingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingAfterAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean> <bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice"/> <bean id="theTracingAfterAdvice" class="TracingAfterAdvice"/>
</beans>
File: TracingAfterAdvice.java import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class TracingAfterAdvice implements AfterReturningAdvice {
public void afterReturning(Object object, Method m, Object[] args, Object target) throws Throwable { System.out.println("Hello world! (by " + this.getClass().getName() + ")"); }
}
File: TracingBeforeAdvice.java import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class TracingBeforeAdvice implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) throws Throwable { System.out.println("Hello world! (by " + this.getClass().getName() + ")"); }
}
File: BusinessLogic.java
public class BusinessLogic implements IBusinessLogic {
public void foo() { System.out.println("Inside BusinessLogic.foo()"); }
}
</source>