Spring基于代理类的AOP实现

动态代理

AOP中的代理就是由AOP实现框架动态生成的一个对象,该对象可以作为目标对象使用。
spring中的AOP代理,可以是JDK动态代理,也可以是CGlib代理

JDK动态代理实现

JDK动态代理是通过java.lang.reflect.Proxy类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象

注意:JDK动态代理,被代理的目标类必须实现接口,才能产生代理对象

  • 创建接口UserService
public interface UserService {
    public void save(String name);
    public String getById(int id);
}
  • 创建实现类UserServiceImpl
public class UserServiceImpl implements UserService{
    
    @Override
    public void save(String name) {
        System.out.println("添加用户:" + name);
    }

    @Override
    public String getById(int id) {
        System.out.println("查询用户,用户id为:" + id);
        return "xiaoming";
    }
}
  • 创建代理类JDKProxy
public class JDKProxy {
    //获取代理
    public Object getProxy(Object tarObj){
        /*
        * 参数一:目标类的类加载器
            参数二:目标类实现的接口
            参数三:回调,代理对象调用方式时执行invoke
        */
        return Proxy.newProxyInstance(tarObj.getClass().getClassLoader(), 
        				tarObj.getClass().getInterfaces(), new InvocationHandler() {

            //代理对象调用方式时执行invoke
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
            													 throws Throwable {
                Object o = method.invoke(tarObj,args);
                System.out.println("JDK其他业务");
                return o;
            }
        });
    }
}
  • 测试
public class ProxyTest {

    public static void main(String[] args) {

        JDKProxy jp=new JDKProxy();
        UserService  us= new UserServiceImpl();//目标类对象
        UserService  usproxy= (UserService) jp.getProxy(us);
        usproxy.save("里么名");
        usproxy.getById(1);
    }
}
  • 结果
    在这里插入图片描述

CDLIB代理实现

JDK动态代理有一定的局限性,就是使用动态代理的对象必须实现一个或多个接口;而CGLIB代理,接口可实现可不实现

  • 上面的接口UserService

  • 上面的实现类UserServiceImpl

  • 创建代理类CGlibProxy

public class CGlibProxy {

    public Object getProxy(Object tarObj){
    	//创建一个动态对象
        Enhancer en=new Enhancer();
        en.setClassLoader(tarObj.getClass().getClassLoader());
        en.setInterfaces(tarObj.getClass().getInterfaces()); //没有实现接口时不需要
        //确定需要增强的类
        en.setSuperclass(tarObj.getClass());
        //添加回调函数
        en.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                Object ob = method.invoke(tarObj,objects);
                System.out.println("CGlib其他业务");
                return ob;
            }
        });
        //返回创建的代理类
        return en.create();
    }
}
  • 测试
public class ProxyTest {

    public static void main(String[] args) {

        CGlibProxy cp = new CGlibProxy();
        UserServiceImpl  us= new UserServiceImpl();//目标类对象
        UserService  usproxy= (UserService) cp.getProxy(us);
        UserServiceImpl  usproxy= (UserServiceImpl) cp.getProxy(us);//没有实现接口

        usproxy.save("水电费");
        usproxy.getById(1);
        

    }
}
  • 结果
    在这里插入图片描述
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值