今天又是周末, 自己的春招也差不多结束了, 百般无聊的状态下想写点东西.
我想先提一个东西, 比如你想要计算一段代码的执行时间, 那么你之前肯定是这样写的.
- /**
- * 先定义一个接口
- *
- * @author chang
- */
- public interface DoSomthing {void doSomthing() throws InterruptedException;
- }
- /**
- * 实现类
- * @author chang
- */
- public class DoSomthingImpl implements DoSomthing {
- @Override
- public void doSomthing() throws InterruptedException {
- Thread.sleep(100);
- System.out.println("这是主体的同容" + System.currentTimeMillis());
- Thread.sleep(100);
- }
- }
写死的方法, 也是最笨的方法.
在 doSomthing 前后加上 before(), after(). 这两个方法. 如果有其他方法想要执行 befor,after, 同样写死在代码里面.
这就是所谓的静态代理, 非常的麻烦以及代码十分的重复冗余, 所以出现了伟大的动态代理.
JDK 动态代理:
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- public class JDKDynamicProxy implements InvocationHandler{
- Object o = null;
- public JDKDynamicProxy(Object o) {
- this.o = o;
- }
- public Object getProxy() {
- return Proxy.newProxyInstance(o.getClass().getClassLoader(),
- o.getClass().getInterfaces(), this);
- }
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- before();
- Object res = method.invoke(o, args);
- after();
- return res;
- }
- void before() {
- System.out.println(System.currentTimeMillis());
- }
- void after() {
- System.out.println(System.currentTimeMillis());
- }
- }
- public class Test {
- public static void main(String[] args) throws InterruptedException {
- JDKDynamicProxy jp = new JDKDynamicProxy(new DoSomthingImpl());
- DoSomthing ds = (DoSomthing) jp.getProxy();
- ds.doSomthing();
- }
- }
会不会发觉扩展十分的方便. 每次只用 new 一个动态代理类, 并且把实现类的对象传过去, jdk 就会自动的代理这个方法.
每次你调用 doSomthing 方法的时候, 自动执行 before 和 after 方法, 非常的方便.
但有个问题, JDK 给我们提供的动态代理只能代理接口, 而不能代理没有接口的类. 因为你的 Proxy.newProxyInstance 要传一个接口的参数过去, 那又要怎么办呢?
CGLib 动态代理
- import java.lang.reflect.Method;
- import net.sf.cglib.proxy.Enhancer;
- import net.sf.cglib.proxy.MethodInterceptor;
- import net.sf.cglib.proxy.MethodProxy;
- public class CGLibDynamicProxy implements MethodInterceptor{
- public CGLibDynamicProxy() {}
- public <T> Object getProxy(Class<T> cls) {
- return Enhancer.create(cls, this);
- }
- @Override
- public Object intercept(Object target, Method arg1, Object[] arg2, MethodProxy proxy) throws Throwable {
- before();
- Object res = proxy.invokeSuper(target, arg2);
- after();
- return res;
- }
- void before() {
- System.out.println(System.currentTimeMillis());
- }
- void after() {
- System.out.println(System.currentTimeMillis());
- }
- }
- public class Test {
- public static void main(String[] args) throws InterruptedException {
- CGLibDynamicProxy cg = new CGLibDynamicProxy();
- DoSomthing ds = (DoSomthing) cg.getProxy(DoSomthingImpl.class);
- ds.doSomthing();
- }
- }
同样 new 一个 CGLibDynamicProxy 对象, 然后通过 getProxy 方法获得对象, 然后直接调用方法即可.
而 Spring 框架底层的 AOP 大概就是用这两种方法实现的.
来源: https://www.cnblogs.com/wenbochang/p/8899626.html