Java/Spring/AOP

Материал из Java эксперт
Перейти к: навигация, поиск

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()");
     }
}