import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface AdviceRequired {
}
import com.apress.prospring5.ch2.common.Guitar;
import com.apress.prospring5.ch2.common.Singer;
public class Guitarist implements Singer {
@Override public void sing() {
System.out.println("Dream of ways to throw it all away");
}
@AdviceRequired
public void sing(Guitar guitar) {
System.out.println("play: " + guitar.play());
}
public void rest(){
System.out.println("zzz");
}
}
import com.apress.prospring5.ch2.common.Guitar;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
public class AnnotationPointcutDemo {
public static void main(String... args) {
Guitarist johnMayer = new Guitarist();
AnnotationMatchingPointcut pc = AnnotationMatchingPointcut
.forMethodAnnotation(AdviceRequired.class);
Advisor advisor = new DefaultPointcutAdvisor(pc, new SimpleAdvice()) ;
ProxyFactory pf = new ProxyFactory();
pf.setTarget(johnMayer);
pf.addAdvisor(advisor);
Guitarist proxy = (Guitarist) pf.getProxy();
proxy.sing(new Guitar());
proxy.rest();
}
}
通过注解实现AOP
import org.springframework.aop.support.NameMatchMethodPointcutAdvisor;
public class NamePointcutUsingAdvisor {
public static void main(String... args) {
GrammyGuitarist johnMayer = new GrammyGuitarist();
NameMatchMethodPointcut pc = new NameMatchMethodPointcut();
pc.addMethodName("sing");
pc.addMethodName("rest");
Advisor advisor =
new NameMatchMethodPointcutAdvisor(new SimpleAdvice());
ProxyFactory pf = new ProxyFactory();
pf.setTarget(johnMayer);
pf.addAdvisor(advisor);
GrammyGuitarist proxy = (GrammyGuitarist) pf.getProxy();
proxy.sing();
proxy.sing(new Guitar());
proxy.rest();
proxy.talk();
}
}
方法名注解
JDK Dynamic Proxy
CGLIB Proxy
public interface SimpleBean {
void advised();
void unadvised();
}
public class DefaultSimpleBean implements SimpleBean {
private long dummy = 0;
@Override
public void advised() {
dummy = System.currentTimeMillis();
}
@Override
public void unadvised() {
dummy = System.currentTimeMillis();
}
}
import java.lang.reflect.Method;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
public class TestPointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class cls) {
return ("advise".equals(method.getName()));
}
}
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class NoOpBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object args, Object target)
throws Throwable {
// no-op
}
}
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultPointcutAdvisor;
public class ProxyPerfTest {
public static void main(String... args) {
SimpleBean target = new DefaultSimpleBean();
Advisor advisor = new DefaultPointcutAdvisor(new TestPointcut(),
new NoOpBeforeAdvice());
runCglibTests(advisor, target);
runCglibFrozenTests(advisor, target);
runJdkTests(advisor, target);
}
private static void runCglibTests(Advisor advisor, SimpleBean target) {
ProxyFactory pf = new ProxyFactory();
pf.setProxyTargetClass(true);
pf.setTarget(target);
pf.addAdvisor(advisor);
SimpleBean proxy = (SimpleBean)pf.getProxy();
System.out.println("Running CGLIB (Standard) Tests");
test(proxy);
}
private static void runCglibFrozenTests(Advisor advisor, SimpleBean target) {
ProxyFactory pf = new ProxyFactory();
pf.setProxyTargetClass(true);
pf.setTarget(target);
pf.addAdvisor(advisor);
pf.setFrozen(true);
SimpleBean proxy = (SimpleBean) pf.getProxy();
System.out.println("Running CGLIB (Frozen) Tests");
test(proxy);
}
private static void runJdkTests(Advisor advisor, SimpleBean target) {
ProxyFactory pf = new ProxyFactory();
pf.setTarget(target);
pf.addAdvisor(advisor);
pf.setInterfaces(new Class{SimpleBean.class});
SimpleBean proxy = (SimpleBean)pf.getProxy();
System.out.println("Running JDK Tests");
test(proxy);
}
private static void test(SimpleBean bean) {
long before = 0;
long after = 0;
System.out.println("Testing Advised Method");
before = System.currentTimeMillis();
for(int x = 0; x < 500000; x++) {
bean.advised();
}
after = System.currentTimeMillis();
System.out.println("Took " + (after - before) + " ms");
System.out.println("Testing Unadvised Method");
before = System.currentTimeMillis();
for(int x = 0; x < 500000; x++) {
bean.unadvised();
}
after = System.currentTimeMillis();
System.out.println("Took " + (after - before) + " ms");
System.out.println("Testing equals() Method");
before = System.currentTimeMillis();
for(int x = 0; x < 500000; x++) {
bean.equals(bean);
}
after = System.currentTimeMillis();
System.out.println("Took " + (after - before) + " ms");
System.out.println("Testing hashCode() Method");
before = System.currentTimeMillis();
for(int x = 0; x < 500000; x++) {
bean.hashCode();
}
after = System.currentTimeMillis();
System.out.println("Took " + (after - before) + " ms");
Advised advised = (Advised)bean;
System.out.println("Testing Advised.getProxyTargetClass() Method");
before = System.currentTimeMillis();
for(int x = 0; x < 500000; x++) {
advised.getTargetClass();
}
after = System.currentTimeMillis();
System.out.println("Took " + (after - before) + " ms");
System.out.println(">>>\n");
}
}
三种代理的性能测试