AOP的实现原理及应用场景

AOP的作用
在不修改源代码的情况下,可以实现功能的增强。

AOP横向抽取思想:基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !

AOP应用场景
场景一:记录日志
场景二:监控方法运行时间 (监控性能)
场景三:权限控制
场景四:缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五:事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
AOP的实现原理
那Spring中AOP是怎么实现的呢?Spring中AOP的有两种实现方式:
JDK动态代理
1.引入依赖,有spring,单元测,日志管理

<dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>

        <!-- 单元测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
</dependencies>

2.新建一个UserDao接口

public interface UserDao {
    public void saveUser();
}

3.新建一个实现类,实现接口

public class userDaoImpl implements userDao{
       public void saveUser(){
       sys........("原有输出");
       }
}

4.动态代理

@Test
public void test1() {

    final UserDao userDao = new UserDaoImpl();
    // newProxyInstance的三个参数解释:
    // 参数1:代理类的类加载器,同目标类的类加载器
    // 参数2:代理类要实现的接口列表,同目标类实现的接口列表
    // 参数3:回调,是一个InvocationHandler接口的实现对象,当调用代理对象的方法时,执行的是回调中的invoke方法
    //proxy为代理对象
    UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(),
            userDao.getClass().getInterfaces(), new InvocationHandler() {

                @Override
                // 参数proxy:被代理的对象
                // 参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法
                // 参数args:执行方法的参数
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("记录日志");
                    Object result = method.invoke(userDao, args);
                    return result;
                }
            });
    //代理对象执行方法
    proxy.saveUser();
}

Cglib动态代理

在实际开发中,可能需要对没有实现接口的类增强,用JDK动态代理的方式就没法实现。采用Cglib动态代理可以对没有实现接口的类产生代理,实际上是生成了目标类的子类来增强。
首先,需要导入Cglib所需的jar包。提示:spring已经集成了cglib,我们已经导入了spring包,所以不需要再导入其它包了。

1.创建LinkManDao类,没有实现任何接口

public class LinkManDao {
    public void save(){
        System.out.println("持久层:联系人保存....");
    }
}

2.动态代理

@Test
public void test2() {
    final LinkManDao linkManDao = new LinkManDao();
    // 创建cglib核心对象
    Enhancer enhancer = new Enhancer();
    // 设置父类
    enhancer.setSuperclass(linkManDao.getClass());
    // 设置回调
    enhancer.setCallback(new MethodInterceptor() {
        /**
         * 当你调用目标方法时,实质上是调用该方法
         * intercept四个参数:
         * proxy:代理对象
         * method:目标方法
         * args:目标方法的形参
         * methodProxy:代理方法
        */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)
                throws Throwable {
            System.out.println("记录日志");
             Object result = method.invoke(linkManDao, args);
            return result;
        }
    });
    // 创建代理对象
    LinkManDao proxy = (LinkManDao) enhancer.create();
    proxy.save();
}

转发自https://mp.weixin.qq.com/s/jrqMdylGGtEv9id3odYqWg

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值