Spring Aop

24 阅读2分钟

springAop

jdk代理代码 (需要实现接口)

接口类

/**
 * @author shenyongqiang
 * @Description:
 * @date 2022/6/3017:22
 */
public interface IHello {
    void sayHello();

    void  aaa();
}

接口实现类
```
public class HelloImpl implements IHello {

    @Override
    public void sayHello() {
        System.out.println("Hello world!");
    }

    @Override
    public void aaa() {
        System.out.println("aaa!");
    }
}
```




```
 */
public class MyInvocationHandler implements InvocationHandler {

    /** 目标对象 */
    private Object target;

    public MyInvocationHandler(Object target){
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("------插入前置通知代码-------------");
        // 执行相应的目标方法
        Object rs = method.invoke(target,args);
        System.out.println("------插入后置处理代码-------------");
        return rs;
    }
}
```

```
public class MyProxyTest {

    public static void main(String[] args)
            throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        // =========================第一种==========================
        // 1、生成$Proxy0的class文件
//        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//        // 2、获取动态代理类
//        Class proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(),IHello.class);
//        // 3、获得代理类的构造函数,并传入参数类型InvocationHandler.class
//        Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
//        // 4、通过构造函数来创建动态代理对象,将自定义的InvocationHandler实例传入
//        IHello iHello1 = (IHello) constructor.newInstance(new MyInvocationHandler(new HelloImpl()));
//        // 5、通过代理对象调用目标方法
//        iHello1.sayHello();


        // ==========================第二种=============================
        /**
         * Proxy类中还有个将2~4步骤封装好的简便方法来创建动态代理对象,
         *其方法签名为:newProxyInstance(ClassLoader loader,Class<?>[] instance, InvocationHandler h)
         */
        IHello  iHello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), // 加载接口的类加载器
                new Class[]{IHello.class}, // 一组接口
                new MyInvocationHandler(new HelloImpl())); // 自定义的InvocationHandler
        iHello2.aaa();
    }
}
```

控制台打印

------插入前置通知代码-------------
aaa!
------插入后置处理代码-------------

Cglib

public class HelloService {
    public HelloService() {
        System.out.println("HelloService构造");
    }

    /**
     * final方法不能被子类覆盖
     * Cglib 是无法代理 final 修饰的方法的
     */
    final public String sayOthers(String name) {
        System.out.println("HelloService:sayOthers>>"+name);
        return null;
    }

    public void sayHello() {
        System.out.println("HelloService:sayHello");
    }
    public void aaa() {
        System.out.println("HelloService:aaa");
    }
}
public class MyMethodInterceptor implements MethodInterceptor {

    /**
     * sub:cglib生成的代理对象
     * method:被代理对象方法
     * objects:方法入参
     * methodProxy: 代理方法
     */
    @Override
    public Object intercept(Object sub, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("======插入前置通知======");
        Object object = methodProxy.invokeSuper(sub, objects);
        System.out.println("======插入后者通知======");
        return object;

    }
}
public class Client {
    public static void main(String[] args) {
        // 代理类class文件存入本地磁盘方便我们反编译查看源码
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "G:\");
        // 通过CGLIB动态代理获取代理对象的过程
        Enhancer enhancer = new Enhancer();
        // 设置enhancer对象的父类
        // 代理类是继承了服务类 !!!
        enhancer.setSuperclass(HelloService.class);
        // 设置enhancer的回调对象
        enhancer.setCallback(new MyMethodInterceptor());
        // 创建代理对象
        HelloService proxy= (HelloService)enhancer.create();
        // 通过代理对象调用目标方法
        proxy.aaa();
    }

}
 打印日志
 
 HelloService构造
======插入前置通知======
HelloService:aaa
======插入后者通知======