​ Spring是方法级别的AOP框架,我们主要也是以某个类的某个方法作为连接点,用动态代理的理论来说,就是要拦截哪个方法织入对应的AOP通知。为了更方便的测试我们首先创建一个接口

public interface RoleService {
public void printRole(Role role);
}

然后创建一个实现类

@Component
public class RoleServiceImpl implements RoleService {
public void printRole(Role role) {
System.out.println(role.toString());
}
}

​ 这个类没啥特别,这个时候把printRole作为AOP的连接点,那么用动态代理的语言就是要为类RoleServiceImpl生成代理对象,然后拦截printRole方法,可以用于产生各种AOP通知方法。

​ 接着我们来进行切面的创建,他如同一个拦截器,在Spring中只要使用@Aspect注解一个类,那么Spring IOC 容器就会认为这是一个切面了。

@Aspect
public class RoleAspect { //在被代理对象的方法前调用 ,使用args来传递参数
@Before("execution(* com.aop.RoleServiceImpl.printRole(..)) && args(role,sort)")
public void before(Role role, int sort) {
System.out.println("before...");
} //在被代理对象的方法后调用
@After("execution(* com.aop.RoleServiceImpl.printRole(..))")
public void after() {
System.out.println("after...");
} //在被代理对象方法正常返回后调用
@AfterReturning("execution(* com.aop.RoleServiceImpl.printRole(..))")
public void afterRunning() {
System.out.println("afterRunning");
} //在被代理对象方法抛出异常后使用
@AfterThrowing("execution(* com.aop.RoleServiceImpl.printRole(..))")
public void afterThrowing() {
System.out.println("afterThrowing");
} //将验证角色对象是否为空的类加入到切面中
//value=""表示对某类进行增强,defaultImpl表示默认的实现类
@DeclareParents(value = "com.aop.RoleServiceImpl+", defaultImpl = RoleVerifierImpl.class)
public RoleVerifier roleVerifier;
}

​ 此时连接点和切面我们都创建完成了,这个时候可以编写代码来测试AOP的内容,首先要对Spring的Bean进行配置,采用注解Java配置。

@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com")
public class AppConfig {
@Bean
public RoleAspect getRoleAspect() {
return new RoleAspect();
}
}

测试AOP流程

public class Main {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
RoleService roleService = (RoleService) ctx.getBean(RoleService.class);
//使用刚才创建的RoleVerifier来进行检测role对象是否为空
RoleVerifier verifier = (RoleVerifier) ctx.getBean(RoleVerifier.class); Role role = new Role();
role.setId(1L);
role.setRoleName("张三");
role.setRoleNote("张三的备注信息");
System.out.println("##测试结果");
roleService.printRole(role);
System.out.println("#####################");
//测试异常通知
role = null;
roleService.printRole(role, 2);
}
}
##测试结果
before...
Role{id=1, roleName='张三', roleNote='张三的备注信息'}
1
afterRunning
after...
#####################
before...
afterThrowing ##异常通知
after...
Exception in thread "main" java.lang.NullPointerException
at com.aop.RoleServiceImpl.printRole(RoleServiceImpl.java:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)

很显然切面的通知已经通过AOP织入约定的流程当中了,这时我们可以使用AOP来处理一些需要切面的场景了。

最新文章

  1. LNMP平台搭建---PHP安装篇
  2. uboot补丁的分析
  3. 在SQL Server中 获取日期、日期格式转换
  4. 服务器进程为何通常fork()两次
  5. js的时间操作方法
  6. 【有趣~】SFOJ-1711 Obey的恋爱、NYOJ-739 笨蛋难题
  7. IOS 如何选择delegate、notification、KVO?(转)
  8. http://nxlhero.blog.51cto.com/962631/1666250?plg_nld=1&plg_uin=1&plg_auth=1&plg_nld=1&plg_usr=1&plg_vkey=1&plg_dev=1
  9. oracle学习----行级锁的理解
  10. 【Cron Expressions】Quartz Scheduler 2.1.x 英文节选
  11. jquery dialog的关闭事件不触发,触发不了
  12. atoi
  13. 走进React
  14. [记录]MySQL 查询无法导出到文件
  15. Android 新架构组件 -- WorkManager
  16. Shell 中字符串变量的赋值注意点
  17. day19常用模块2
  18. 关于 f 散度
  19. java多线程入门学习(一)
  20. python, Django 的安装

热门文章

  1. iframe引入微信公众号文章
  2. 在Blazor中实现拖放(drag and drop)
  3. springboot打包时候忽略编译测试类
  4. Python学习进度汇报
  5. 新手入门C语言第九章:C函数
  6. Java语言学习day34--8月09日
  7. vue项目中cookie的使用
  8. FreeRTOS --(13)任务管理之空闲任务
  9. 开发一个不需要重写成Hive QL的大数据SQL引擎
  10. ONNXRuntime学习笔记(三)