springboot2原理实战(17)

文章目录 目录一、使用aop小demo认识开发流程1:spring-boot-start-aop 加入依赖,默认开启了Aop的支持2:写一个Aspect,封装横切关注点(日志,监控等待),需要配置前置通知,后置通知等待,和切入点,哪些包的哪些类的方法等等3.测试: 二、了解springboot的代理和切换代理操作1.默认的动态代理cglib2.切换成jdk动态代理 三、使用aop获取切面参数四、EnableAspectJAutoProxy获取代理对象

目录

本文的主要内容如下:

一、使用aop小demo认识开发流程 1:spring-boot-start-aop 加入依赖,默认开启了Aop的支持 org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine

写个被切入的类:

@Repositorypublic class UserDao { public void add(String username, String password){ System.out.println(“add 【username:”+username+”,password:”+password+”】”); }} 2:写一个Aspect,封装横切关注点(日志,监控等待),需要配置前置通知,后置通知等待,和切入点,哪些包的哪些类的方法等等

这个Aspect需要@Component纳入到spring容器管理,并且需要纳入spring管理:

@Aspect@Componentpublic class LogAspect { @Before(“execution(* com.springboot.demo17.dao..*.*(..))”) public void log(){// System.out.println(“before method log done “+ AopContext.currentProxy().getClass()); System.out.println(“before method log done”); } } 3.测试: @SpringBootApplicationpublic class Demo17Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args); System.out.println(context.getBean(UserDao.class).getClass()); context.getBean(UserDao.class).add(“admin”,”123″); context.close(); }

运行结果: 显示aop已经生效。

二、了解springboot的代理和切换代理操作

看下aop自动配置的类:

通过源码,我们可以看到,

1.spring.aop”, name = “auto”, havingValue = “true”,说明springboot默认为我们开启Aop我们可以通过这个spring.auto来设置是否开启关闭。2.springboot2默认是使用的cglib代理。我们可以使用spring.aop.proxy-target-class的true和fasle,来切换代理模式是cglib还是jdk动态代理。true代表cglib,false代表jdk动态代理。 1.默认的动态代理cglib

刚才的aop入门小demo的控制台打印看下: 在这里插入图片描述 这里也说明我们的确是使用的cglib

2.切换成jdk动态代理

我们知道jdk动态代理是面向接口的,现在设置下: 写一个接口:

public interface IuserDao { public void add(String username, String password);} @Repositorypublic class UserDao implements IuserDao{ public void add(String username, String password){ System.out.println(“add 【username:”+username+”,password:”+password+”】”); }}

配置文件修改动态代理方式:

spring.aop.auto=truespring.aop.proxy-target-class=false

打印查看:

@SpringBootApplicationpublic class Demo17Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args); System.out.println(context.getBean(UserDao.class).getClass()); // context.getBean(UserDao.class).add(“admin”,”123″); context.close(); }}

测试类:

@SpringBootApplicationpublic class Demo17Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args); //得用接口获取对象 System.out.println(context.getBean(IuserDao.class).getClass()); context.getBean(IuserDao.class).add(“admin”,”123″); context.close(); }}

运行,控制台打印: 在这里插入图片描述 显示已经是java的jdk动态代理了。 特别注意: UserDao必须实现个IUserDao的接口,必须通过接口获取实例,不然使用的还是cglib动态代理。

三、使用aop获取切面参数

拿到切面里面的类或者参数,可以通过JoinPoint point 在这里插入图片描述 这里有上面几个方法,可以通过getTarget获取类,getArgs获取方法的参数,getSignature().获取方法名称。 测试下: 改下编织类,添加个after后置织入:

@Aspect@Componentpublic class LogAspect { @Before(“execution(* com.springboot.demo17.dao..*.*(..))”) public void log(){// System.out.println(“before method log done “+ AopContext.currentProxy().getClass()); System.out.println(“before method log done”); } @After(“execution(* com.springboot.demo17.dao..*.*(..))”) public void logAfter(JoinPoint point){ System.out.println(“after method log done”+point.getTarget().getClass()+”,args=”+ Arrays.asList(point.getArgs())+”,method=”+point.getSignature().getName()); }}

测试:

@SpringBootApplicationpublic class Demo17Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args); System.out.println(context.getBean(UserDao.class).getClass()); // context.getBean(UserDao.class).add(“admin”,”123″); context.close(); }}

运行入口函数,控制台打印: 在这里插入图片描述 显示切面里面的类和参数和方法名都已经获取到了。

四、EnableAspectJAutoProxy获取代理对象

看下这个类的源码:

在这里插入图片描述 有2个属性:

proxyTargetClass: 这个属性也可以切换动态代理方式,true代表cglib,false是jdk动态代理

exposeProxy: 这个属性设置为true可以获取到代理对象是谁。 设置为true,可以获取到AopContext对象: 在这里插入图片描述

现在测试下: 修改织入类:

@Aspect@Componentpublic class LogAspect { @Before(“execution(* com.springboot.demo17.dao..*.*(..))”) public void log(){ System.out.println(“before method log done “+ AopContext.currentProxy().getClass()); System.out.println(“before method log done”); } }

入口函数,设置可获取代理对象:@EnableAspectJAutoProxy(exposeProxy = true):

@EnableAspectJAutoProxy(exposeProxy = true)@SpringBootApplicationpublic class Demo17Application { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(Demo17Application.class, args); System.out.println(context.getBean(UserDao.class).getClass()); // context.getBean(UserDao.class).add(“admin”,”123″); context.close(); }}

运行,控制台打印如下: 在这里插入图片描述 可以看到,代理对象是:EnhancerBySpringCGLIB.

本文,主要讲laop如何使用,如何切换动态代理,如何拿到动态代理的参数,如何获取代理对象。

个人微信公号: 搜索: 怒放de每一天 不定时推送相关文章,期待和大家一起成长!! 在这里插入图片描述


比丘资源网 » springboot2原理实战(17)

提供最优质的资源集合

立即查看 了解详情