点击关注公众号,利用碎片时间学习
AOP的作用
作用:在不修改源代码的情况下,可以实现功能的增强。
传统的纵向体系代码复用:
横向抽取机制(AOP思想):
AOP 思想:基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !
AOP应用场景
场景一:记录日志
场景二:监控方法运行时间 (监控性能)
场景三:权限控制
场景四:缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五:事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
AOP的实现原理
那Spring中AOP是怎么实现的呢?Spring中AOP的有两种实现方式:
JDK动态代理
Cglib动态代理
扩展:手动实现一个迷你版的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接口
publicinterfaceUserDao{publicvoidsaveUser();}
3.UserDao实现类
publicclassUserDaoImplimplementsUserDao{@OverridepublicvoidsaveUser(){System.out.println("持久层:用户保存");}}
4.动态代理
@Testpublicvoidtest1(){finalUserDaouserDao=newUserDaoImpl();// newProxyInstance的三个参数解释://参数1:代理类的类加载器,同目标类的类加载器//参数2:代理类要实现的接口列表,同目标类实现的接口列表//参数3:回调,是一个InvocationHandler接口的实现对象,当调用代理对象的方法时,执行的是回调中的invoke方法//proxy为代理对象UserDaoproxy=(UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(),newInvocationHandler(){@Override//参数proxy:被代理的对象//参数method:执行的方法,代理对象执行哪个方法,method就是哪个方法//参数args:执行方法的参数publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{System.out.println("记录日志");Objectresult=method.invoke(userDao,args);returnresult;}});//代理对象执行方法proxy.saveUser();}
5.结果
在没有修改原有类的代码的情况下,对原有类的功能进行了增强
Cglib动态代理
在实际开发中,可能需要对没有实现接口的类增强,用JDK动态代理的方式就没法实现。采用Cglib动态代理可以对没有实现接口的类产生代理,实际上是生成了目标类的子类来增强。
首先,需要导入Cglib所需的jar包。提示:spring已经集成了cglib,我们已经导入了spring包,所以不需要再导入其它包了。
1.创建LinkManDao类,没有实现任何接口
publicclassLinkManDao{publicvoidsave(){System.out.println("持久层:联系人保存....");}}
2.动态代理
@Testpublicvoidtest2(){finalLinkManDaolinkManDao=newLinkManDao();//创建cglib核心对象Enhancerenhancer=newEnhancer();//设置父类enhancer.setSuperclass(linkManDao.getClass());//设置回调enhancer.setCallback(newMethodInterceptor(){/***当你调用目标方法时,实质上是调用该方法* intercept四个参数:*proxy:代理对象*method:目标方法* args:目标方法的形参*methodProxy:代理方法*/@OverridepublicObjectintercept(Objectproxy,Methodmethod,Object[]args,MethodProxymethodProxy)throwsThrowable{System.out.println("记录日志");Objectresult=method.invoke(linkManDao,args);returnresult;}});//创建代理对象LinkManDaoproxy=(LinkManDao)enhancer.create();proxy.save();}
3.结果
(感谢阅读,希望对你所有帮助)
来源:guguoyu./article/details/80868392
推荐好文
强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!
分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范!
能挣钱的,开源 SpringBoot 商城系统,功能超全,超漂亮