SSM——AOP动态代理——day03

1、Spring核心-AOP-动态代理-基于JDK代理1

1、动态代理:

            静态代理:要求代理类一定存在,
            动态代理:程序运行的时候,根据要被代理的对象动态生成代理类。
            类型: 1 、基于 JDK 的动态代理
                       2 、基于 CGLIB 的动态代理
2、举个例子来感受一下 jdk 动态代理
需要用到的一些类
import com.zj.aop.AOP;
public class LogAopImpl implements AOP {
    /**
     * 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
     */
    @Override
    public void before() {
        System.out.println("日志---------before----------");
    }

    @Override
    public void after() {
        System.out.println("日志---------after----------");
    }

    @Override
    public void exception() {
        System.out.println("日志---------exception----------");
    }

    @Override
    public void myFinally() {
        System.out.println("日志---------myFinally----------");
    }
}
import com.zj.aop.AOP;
public class TranAop implements AOP {
    /**
     * 切面:服务代码,切到核心代码当中去。切入到那里,我们举例子,给了四个位置;
     */
    @Override
    public void before() {
        System.out.println("事务----------before--------");
    }

    @Override
    public void after() {
        System.out.println("事务----------after--------");
    }

    @Override
    public void exception() {
        System.out.println("事务----------exception--------");
    }

    @Override
    public void myFinally() {
        System.out.println("事务----------myFinally--------");
    }
}
创建一个包,包里面创建一个类MyJdkProxy
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyJdkProxy {
    public static void main(String[] args) {
        //目标对象---------被代理对象
        TeamService teamService = new TeamServiceImpl();
        //返回代理对象,基于jdk的动态代理
        TeamService proxyService = (TeamService) Proxy.newProxyInstance(teamService.getClass().getClassLoader(), teamService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                try {
                    System.out.println("事务开始");
                    Object invoke = method.invoke(teamService, args);//核心方法
                    System.out.println("事务结束");
                    return invoke;
                }catch (Exception e){
                    System.out.println("事务回滚");
                    e.printStackTrace();
                    throw e;
                }finally {
                    System.out.println("finally----------");
                }
            }
        });
        //让代理对象干活
        proxyService.add();

        //获取各自的类型
        System.out.println(teamService.getClass());
        System.out.println(proxyService.getClass());
    }
}

结果:

事务开始
TeamService-----add-----
事务结束
finally----------
class com.zj.service.impl.TeamServiceImpl
class com.sun.proxy.$Proxy0

让我们来对上面的代码进行一个优化

创建一个proxyHandler对象

import com.zj.aop.AOP;
import com.zj.service.TeamService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {

    //被代理的对象,采用的是接口的形式
    private TeamService teamService;

    //切面对象
    private AOP aop;

    //定义一个全参构造方法,让我们在创建对象的时候定义好他们。
    public ProxyHandler(TeamService teamService, AOP aop) {
        this.teamService = teamService;
        this.aop = aop;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        try {
            aop.before();
            Object invoke = method.invoke(teamService, args);//核心方法
            aop.after();
            return invoke;
        }catch (Exception e){
            aop.exception();
            e.printStackTrace();
            throw e;
        }finally {
            aop.myFinally();
        }
    }
}
import com.zj.aop.AOP;
import com.zj.aop.impl.LogAopImpl;
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;
import java.lang.reflect.Proxy;

public class MyJdkProxy {
    public static void main(String[] args) {
        //目标对象---------被代理对象
        TeamService teamService = new TeamServiceImpl();
        //创建切面对象
        AOP logAop = new LogAopImpl();
        //返回代理对象,基于jdk的动态代理
        TeamService service = (TeamService) Proxy.newProxyInstance(teamService.getClass().getClassLoader(), teamService.getClass().getInterfaces(),
                new ProxyHandler(teamService, logAop));
        //让代理对象干活
        service.add();
    }
}

再次优化

创建一个产生代理对象的工产:

import com.zj.aop.AOP;
import com.zj.service.TeamService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactory {

    //被代理类
    private TeamService teamService;
    private AOP aop;

    public ProxyFactory(TeamService teamService, AOP aop) {
        this.teamService = teamService;
        this.aop = aop;
    }

    public Object getProxyInstance(){
        return Proxy.newProxyInstance(
                teamService.getClass().getClassLoader(),
                teamService.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        try {
                            aop.before();
                            Object invoke = method.invoke(teamService, args);
                            aop.after();
                            return invoke;
                        }catch (Exception e) {
                            e.printStackTrace();
                            return e;
                        } finally {
                            aop.myFinally();
                        }
                    }
                }
        );
    }
}

测试类:

import com.zj.aop.AOP;
import com.zj.aop.impl.LogAopImpl;
import com.zj.aop.impl.TranAop;
import com.zj.service.TeamService;
import com.zj.service.impl.TeamServiceImpl;

public class MyJdkProxy {
    public static void main(String[] args) {
        //目标对象---------被代理对象
        TeamService teamService = new TeamServiceImpl();
        //创建切面对象
        AOP logAop = new LogAopImpl();
        AOP tranAop = new TranAop();
        //返回代理对象,基于jdk的动态代理
        TeamService service = (TeamService) new ProxyFactory(teamService, logAop).getProxyInstance();
        TeamService service1 = (TeamService) new ProxyFactory(service, tranAop).getProxyInstance();
        //让代理对象干活
        service1.add();
    }
}

4、jdk动态代理的总结:

代理对象不需要实现接口,但是目标对象一定要实现接口;否则不能用 JDK 动态代理

3、Spring核心-AOP-动态代理-基于CGLIB代理1

1、如果想要功能扩展,但目标对象没有实现接口,怎样功能扩展。我们可以根据子类的方式实

     现动态代理CGLIB。

2、Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。

   JDK 的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没     有 实现接口的类,就可以使用CGLIB 实现。 CGLIB是一个强大的高性能的代码生成包,它可以     在运行期扩展 Java 类与实现 Java 接口。它广泛的 被许多AOP 的框架使用,例如 Spring                     AOP   和   dynaop ,为他们提供方法的 interception 。 CGLIB包的底层是通过使用一个小而快的字    节码处理框架 ASM ,来转换字节码并生成新的类。不鼓 励直接使用ASM ,因为它要求你必须           对  JVM 内部结构包括 class 文件的格式和指令集都很熟悉。
3、通过一个小小的案例来说明一下使用方法:
1)在pom.xml中导入cglib的依赖包
<dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.2</version>
</dependency>

2)创建一个包cglibProxy,在包中创建一个类,MyCglibProxy,在创建一个类,不实现任何接口

NBAService类

package com.zj.cglibProxy;

public class NBAService {
    public int add(int a,int b){
        return a+b;
    }
}

MyCglibProxy类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class MyCglibProxy {
    public static void main(String[] args) {
        //被代理类
        NBAService nbaService = new NBAService();
        //创建代理对象,选择cglib动态代理
        //这里的代理和被代理的类的类型相同
        NBAService service = (NBAService) Enhancer.create(nbaService.getClass(),
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        try {
                            System.out.println("开始事务");
                            methodProxy.invokeSuper(o, objects);//核心
                            System.out.println("结束事务");
                            return null;
                        } catch (Exception e) {
                            System.out.println("事务回滚");
                            return e;
                        } finally {
                            System.out.println("finally------------");
                        }
                    }
                });

        //带代理对象执行任务
        int sum = service.add(1, 2);
        System.out.println(sum);
    }
}

将main方法中的cglibProxy运用结构化一下

在同一个包下创建一个cglibProxyFactory类:

import com.zj.aop.AOP;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class CglibProxyFactory {

    //定义一个被代理的对象
    private NBAService nbaService;
    //定义切面
    private AOP aop;

    //写一个方法,返回的是代理对象
    public Object getProxyInstance(NBAService nbaService, AOP aop){
       return Enhancer.create(nbaService.getClass(),
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        try {
                            aop.before();
                            Object o1 = methodProxy.invokeSuper(o, objects);
                            aop.after();
                            return null;
                        } catch (Exception e) {
                            aop.exception();
                            return e;
                        } finally {
                            aop.myFinally();
                        }
                    }
                });
    }
}

测试类

public static void main(String[] args) {
        //被代理类
        NBAService nbaService = new NBAService();
        //创建切面
        AOP tranAop = new TranAop();
        AOP logAop = new LogAopImpl();

        //创建工厂类
        NBAService service =(NBAService) new CglibProxyFactory().getProxyInstance(nbaService,tranAop);
        NBAService service1 =(NBAService) new CglibProxyFactory().getProxyInstance(service,logAop);
        //让代理类去干活

        int sum = service1.add(1, 2);
        System.out.println(sum);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值