1.Spring对动态代理的支持
下图可以看到AopProxy接口实现了JDK和Cglib方式的动态代理支持,AopProxyFactory则负责创建AopProxy
2.JdkDynamicAopProxy的使用
我们先从JdkDynamicAopProxy的实际使用开始着手
代码示例1-JdkDynamicAopProxy的使用
@Test
public void testProxyIsJustInterface() throws Throwable {
TestBean raw = new TestBean();
raw.setAge(32);
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
pc.setTarget(raw);
JdkDynamicAopProxy aop = new JdkDynamicAopProxy(pc);
ITestBean proxy = (ITestBean) aop.getProxy();
proxy.setName("test");
assertTrue(proxy instanceof ITestBean);
assertFalse(proxy instanceof TestBean);
}
JdkDynamicAopProxy构造函数需要传入一个AdvisedSupport
3.AdvisedSupport
3.1 Advised
Advised接口提供了管理Advice接口以及Advisor接口的功能,Advice接口即增强类,会在方法执行前后执行,Advisor看3.3介绍
3.2 关于Advice的介绍
代码示例2-使用AdvisedSupport添加Advice
@Test
public void testProxy2() throws Throwable {
TestBean raw = new TestBean();
raw.setAge(32);
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
pc.setTarget(raw);
{
MethodBeforeAdvice mi = new MethodBeforeAdvice()
{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("before");
}
};
pc.addAdvice(mi);
}
{
AfterReturningAdvice mi = new AfterReturningAdvice()
{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("after");
}
};
pc.addAdvice(mi);
}
JdkDynamicAopProxy aop = new JdkDynamicAopProxy(pc);
ITestBean proxy = (ITestBean) aop.getProxy();
proxy.setName("test");
assertTrue(proxy instanceof ITestBean);
assertFalse(proxy instanceof TestBean);
}
输出结果:
before
setName
after
3.3 Advisor
Advisor是Pointcut和Advice的组合,比如上面的例子, ITestBean每次调用方法都会执行Advice相关代码,Pointcut相当于添加执行的条件,比如只在调用setName方法的时候执行
代码示例3-使用AdvisedSupport添加Advisor
class TestBeanAdvisor extends StaticMethodMatcherPointcutAdvisor {
public int count;
public TestBeanAdvisor() {
setAdvice(new MethodBeforeAdvice() {
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
System.out.println("before");
}
});
}
@Override
public boolean matches(Method method, @Nullable Class> targetClass) {
return method.getName().equals("setName");
}
}
@Test
public void testProxy3() throws Throwable {
TestBean raw = new TestBean();
raw.setAge(32);
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
pc.setTarget(raw);
pc.addAdvisor(new TestBeanAdvisor());
JdkDynamicAopProxy aop = new JdkDynamicAopProxy(pc);
ITestBean proxy = (ITestBean) aop.getProxy();
proxy.setName("test");
proxy.setAge(2);
assertTrue(proxy instanceof ITestBean);
assertFalse(proxy instanceof TestBean);
}
4.DefaultAopProxyFactory
可以用DefaultAopProxyFactory来根据ProxyConfig参数(AdvisedSupport)来动态创建AopProxy,比如设置optimize为true,则为cglib动态代理对象
使用DefaultAopProxyFactory创建AopProxy
@Test
public void testProxy4() throws Throwable {
TestBean raw = new TestBean();
raw.setAge(32);
AdvisedSupport pc = new AdvisedSupport(ITestBean.class);
pc.setTarget(raw);
pc.addAdvisor(new TestBeanAdvisor());
pc.setOptimize(true);
AopProxyFactory aopProxyFactory=new DefaultAopProxyFactory();
AopProxy aop = aopProxyFactory.createAopProxy(pc);
ITestBean proxy = (ITestBean) aop.getProxy();
proxy.setName("test");
proxy.setAge(2);
}
参考:
http://book.51cto.com/art/200908/147288.htm
https://www.jianshu.com/p/1dd6a26c881b