Spring AOP是通过动态代理实现的:通过JDK的动态代理或者CGLIB动态生成子类.
如果被代理的bean是interface,会使用JDK的动态代理,这时候,bean的构造函数只会被调用一次,如果该bean没有实现任何interface,会使用cglib来动态生成子类,这时候构造函数会被调用两次,所以在bean的构造函数里尽量不要写业务相关的代码.
如果bean的某个方法被'AOP'了,及对该方法加入了方面关注:'advice',如funcA,另一个该类的方法,如funcB,调用funcA.客户端代码调用了
funcB,虽然funcB会调用funcA,但是关注点方法不会被执行.例子:
public class IntfBean implements Intf{
public IntfBean() {
System.out.println("IntfBean construcgtor");
}
@Override
public void test1() {
System.out.println("Intf test");
}
public void test2() {
test1();
}
}
public interface Intf {
public void test1();
public void test2();
}
切面配置:
@Pointcut("execution(* com.test.spring.aspectj.Intf.test1(..))")
public void guardIntf() {
}
@Before(value = "guardIntf()")
public void guardIntfBefore() {
System.out.println("Guardian caught before guardIntf");
}
@AfterReturning("guardIntf()")
public void guardIntfAfter() {
System.out.println("Guardian caught after guardIntf ");
}
调用代码:
ApplicationContext context = new ClassPathXmlApplicationContext("conf/aspectJAppcontext.xml");
Intf intfBean = (Intf) context.getBean("IntfBean");
try {
intfBean.test2();
} catch (Exception e) {
}
运行结果:
构造函数执行一次(因为是interface,如果不是会执行两次)
关注点方法(guardIntfBefore和guardIntfAfter)不执行.如果客户端调用: intfBean.test1(),关注点方法(guardIntfBefore和guardIntfAfter)会执行.