一、使用jdk自带的动态代理机制:
- 定义一个普通的接口及实现类;
- 定义一个InvocationHandler的实现类用于织入横向插入的操作(此处为打印信息);
- 生成接口的代理类;
- 调用接口方法,实现动态代理。
-
package aopdemo.jdk; public interface INormalService { public void service(); }
package aopdemo.jdk; public class NormalServiceImpl implements INormalService { @Override public void service() { System.out.println("invoke service"); } }
package aopdemo.jdk; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before service"); Object object = method.invoke(target, args); System.out.println("after service"); return object; } }
package aopdemo.jdk; import java.lang.reflect.Proxy; public class JdkProxyDemo { public static void main(String[] args) { INormalService normalService = new NormalServiceImpl(); MyInvocationHandler handler = new MyInvocationHandler(normalService); INormalService iNormalService = (INormalService) Proxy .newProxyInstance(normalService.getClass().getClassLoader(), normalService.getClass().getInterfaces(), handler); iNormalService.service(); } }
执行结果为:
before service
invoke service
after service
二、使用Cglib实现动态代理
- 定义一个普通的类;
- 定义一个MethodInterceptor的实现类用于织入横向插入的操作(此处为打印信息);
- 使用enhancer增强器生成普通类的代理类;
- 调用代理类的方法,实现动态代理。
package aopdemo.cglib; public class NormalServiceImpl { public void service() { System.out.println("invoke service"); } }
package aopdemo.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before service"); Object object = proxy.invokeSuper(obj, args); System.out.println("after service"); return object; } }
package aopdemo.cglib; import net.sf.cglib.proxy.Enhancer; public class CglibDemo { public static void main(String[] args) { CglibProxy cglibProxy = new CglibProxy(); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(NormalServiceImpl.class); enhancer.setCallback(cglibProxy); NormalServiceImpl normalServiceImpl = (NormalServiceImpl) enhancer .create(); normalServiceImpl.service(); } }
最后输出:
before service
invoke service
after service
三、总结
jdk代理只能动态代理接口;
Cglib代理可以代理普通的类。
四、spring如何配置代理方式?
<aop:aspectj-autoproxy proxy-target-class="true" />
若配为true表示强制使用Cglib来代理;
若不配为true:
如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制);
如果要被代理的对象不是个实现类,Spring会强制使用Cglib来实现动态代理。