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
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();
}
}
Annotation Component
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();
}
}
Annotation Scope
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();
}
}
AOP Annotation
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);
}
}
Aspect Annotation
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();
}
}
Aspect Annotation Pointcut AroundAfter
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;
}
}
Aspect Filter
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));
}
}
}
AspectJ AutoProxy
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) {
}
}
AspectJ Expression Pointcut
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);
}
}
ComposablePointcut Intersection
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);
}
}
ComposablePointcut Union
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);
}
}
Concurrency Throttle Interceptor
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);
}
}
Customizable TraceInterceptor
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);
}
}
Jdk Regexp Method Pointcut
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");
}
}
Matcher For Getter And Setter
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);
}
}
Method Lookup
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");
}
}
Spring AOP Examples
Spring Tracing Aspect
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>
<!--CONFIG-->
<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>
<!--CLASS-->
<bean id="beanTarget"
class="BusinessLogic"/>
<!--ADVISOR-->
<!--Note: An advisor assembles pointcuts and advice-->
<bean id="theTracingBeforeAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingBeforeAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
<!--ADVISOR-->
<!--Note: An advisor assembles pointcuts and advice-->
<bean id="theTracingAfterAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref local="theTracingAfterAdvice"/>
</property>
<property name="pattern">
<value>.*</value>
</property>
</bean>
<!--ADVICE-->
<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()");
}
}